興味深い質問です。Linuxでも同様の問題があります。OSSEC や tripwire などの侵入検知システムは、実行可能ファイルのハッシュサムが突然変更されると、誤検知を生成する可能性があります。これは、起動を高速化するために実行可能ファイルにパッチを適用する Linux の「プレリンク」プログラムよりも悪いことではありません。
2 つのバイナリ ( ELF 形式) を比較するには、「readelf」実行可能ファイルを使用してから「diff」を使用して出力を比較します。洗練された解決策があると確信していますが、これ以上苦労することなく、Perl の貧弱なコンパレーター:
#!/usr/bin/perl -w
$exe = $ARGV[0];
if (!$exe) {
die "Please give name of executable\n"
}
if (! -f $exe) {
die "Executable $exe not found or not a file\n";
}
if (! (`file '$exe'` =~ /\bELF\b.*?\bexecutable\b/)) {
die "file command says '$exe' is not an ELF executable\n";
}
# Identify sections in ELF
@lines = pipeIt("readelf --wide --section-headers '$exe'");
@sections = ();
for my $line (@lines) {
if ($line =~ /^\s*\[\s*(\d+)\s*\]\s+(\S+)/) {
my $secnum = $1;
my $secnam = $2;
print "Found section $1 named $2\n";
push @sections, $secnam;
}
}
# Dump file header
@lines = pipeIt("readelf --file-header --wide '$exe'");
print @lines;
# Dump all interesting section headers
@lines = pipeIt("readelf --all --wide '$exe'");
print @lines;
# Dump individual sections as hexdump
for my $section (@sections) {
@lines = pipeIt("readelf --hex-dump='$section' --wide '$exe'");
print @lines;
}
sub pipeIt {
my($cmd) = @_;
my $fh;
open ($fh,"$cmd |") or die "Could not open pipe from command '$cmd': $!\n";
my @lines = <$fh>;
close $fh or die "Could not close pipe to command '$cmd': $!\n";
return @lines;
}
たとえば、マシン 1 で次のように実行できます。
./checkexe.pl /usr/bin/curl > curl_machine1
そして、マシン 2 では:
./checkexe.pl /usr/bin/curl > curl_machine2
ファイルを同じファイルツリーにコピーペースト、SFTP または NSF (FTP は使用しませんか?) した後、ファイルを比較します。
diff --side-by-side --width=200 curl_machine1 curl_machine2 | less
私の場合、セクション「.gnu.conflict」、「.gnu.liblist」、「.got.plt」、および「.dynbss」に違いがあり、「プレリンク」介入には問題ないかもしれませんが、コードセクションにあります、「.text」、これは悪い兆候です。