9

同じコンパイラ/フラグを使用してコンパイルされた 2 つの実行可能ファイルや共有オブジェクトを比較し、それらが変更されていないことを確認する必要があります。私たちは規制された環境で作業しているため、テスト目的で実行可能ファイルのどの部分が変更されたかを正確に特定することは非常に役立ちます。

ファイルに関する情報がヘッダーに含まれているため、MD5Sums/Hashes の使用は機能しません。

2 つのファイルが異なる時間にビルドされた場合でも、実行上同じであることを確認するプログラムまたは方法を知っている人はいますか?

4

4 に答える 4

5

興味深い質問です。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」、これは悪い兆候です。

于 2011-11-15T18:54:25.550 に答える
1

フォローアップするために、ここに私が最終的に思いついたものがあります:

最終的な実行可能ファイルと共有オブジェクトを比較する代わりに、リンクする前に出力された .o ファイルを比較しました。リンクプロセスは十分に再現可能であり、これで問題ないと想定しました。

一部のケースでは機能します.2つのビルドがあり、最終的なコードに影響を与えない小さな変更を加えましたが(Code pretty-printer)、ビルドの中間出力がない場合は役に立ちません.

于 2011-02-11T16:07:57.467 に答える
0

ELF ファイルからバイナリ ファイルを生成することにより、RO および RW で初期化されたセクションの内容を比較できます。

objcopy <elf_file> -O binary <binary_file>

diff生成されたバイナリ ファイルを使用して、たとえばを使用して同一かどうかを比較します。

私の意見では、これは、同じ実行可能ファイルを生成していることを認めるには十分です。

于 2018-09-26T15:06:46.013 に答える
-1

数年前、私は同じことをしなければなりませんでした。リビジョン番号、リビジョン管理リポジトリ、ビルド ツール、およびビルド構成のみが与えられた場合に、ソースから実行可能ファイルを再構築できることを証明する必要がありました。注:これらのいずれかが変更された場合、違いが見られる場合があります。

実行可能ファイルにいくつかのタイムスタンプがあることを覚えています。秘訣は、ファイルが解釈できない単なるバイトの集まりではないことを理解することです。ファイルにはセクションがあり、ほとんどは変更されませんが、ビルド時 (またはそのようなもの) のセクションがあります。

すべての詳細を覚えているわけではありませんが、必要なコマンドは { objcopy, objdump, nm }です。最初に試すのはobjdumpだと思います。

お役に立てれば。

于 2013-10-04T12:54:29.013 に答える