30

2 つの .NET アセンブリを比較して、それらが「同じ」ソース ファイルからビルドされたかどうかを判断する方法を知っている人はいますか?

Reflector のプラグインなど、いくつかの差分ユーティリティが利用できることは承知していますが、GUI で差分を表示することに興味はありません。同じ (または同等の) ソース ファイル。複数の異なるソース ファイルが同じ IL を生成する可能性があることを理解しており、そのプロセスは元のソースではなく、IL の違いにのみ影響を受けることを認識しています。

2 つのアセンブリのバイト ストリームを比較するだけの主な障害は、.NET にアセンブリに "MVID" (Module Version Identifier) と呼ばれるフィールドが含まれていることです。これは、コンパイルごとに異なる値を持つように見えるため、同じコードを 2 回ビルドすると、アセンブリが異なります。

関連する質問は、コンパイルごとにMVIDを強制的に同じにする方法を知っている人はいますか? これにより、MVID の値の違いに影響されない比較プロセスを使用する必要がなくなります。標準のチェックサムを使用できることを意味するため、一貫した MVID が望ましいでしょう。

この背景には、本番環境へのリリースが許可される前に、サードパーティ企業がリリースを独自にレビューして承認する責任があるということがあります。これには、ソース コードのレビューが含まれます。彼らは、私たちが提供するソース コードが、私たちが以前に構築、テストし、現在展開を計画しているバイナリと一致することを独自に確認したいと考えています。私たちが提供するソースからシステムを独自に構築し、チェックサムをテスト済みのバイナリのチェックサムと比較できるプロセスを探しています。

ところで。継続的インテグレーション、自動ビルド、ソース管理などを使用していることに注意してください。この問題は、特定のビルドにどのソース ファイルが入ったかを内部で制御できないこととは関係ありません。問題は、サード パーティが、サード パーティに提供するソースが、テスト済みで本番環境に入れる予定のバイナリと同じバイナリを生成することを確認する責任があることです。ビルド サーバーやソース コード管理システムを含め、内部システムやコントロールを信頼するべきではありません。彼らが関心を持っているのは、ビルドに関連付けられたソースを取得し、ビルド自体を実行し、出力がデプロイしようとしているものと一致することを確認することだけです。

比較ソリューションの実行速度は特に重要ではありません。

ありがとう

4

7 に答える 7

10

コマンド ライン ツールを使用して、IL のテキスト表現から MVID と日時スタンプを除外するのはそれほど面倒ではありません。file1.exe と file2.exe が同じソースからビルドされているとします。

c:\temp> ildasm /all /text file1.exe | find /v "日時スタンプ:" | 検索 /v "MVID" > file1.txt

c:\temp> ildasm /all /text file2.exe | find /v "日時スタンプ:" | 検索 /v "MVID" > file2.txt

c:\temp> fc ファイル1.txt ファイル2.txt

ファイル file1.txt と FILE2.TXT の比較

FC: 違いはありません

于 2010-07-07T13:51:06.370 に答える
8

クラスライブラリをILDasmV4.0.319.1と比較すると、イメージベースが初期化されていないようです。不一致を回避するには、改訂されたソリューションを使用します。

ildasm /all /text assembly.dll
| find /v "// Time-date stamp:"
| find /v "// MVID:"
| find /v "// Checksum:"
| find /v "// Image base:"
> assembly.dasm

エントリポイント(イメージベース)は、実行可能アセンブリにとって実際には興味深い情報であり、慎重に検証する必要があります。新しい画像ベースを挿入することは、プログラムにまったく別のことをさせる一般的な方法です。私の場合、マルチスレッドビルドの整合性を検証しようとしているので、エントリポイントをスキップしても安全です。

パフォーマンスに関する注意:AnyCPU用に構築された8MBのDLLを取得し、ILDasmを実行しました。結果のファイルのサイズは251MBで、作成には数分かかりました。約32倍のサイズが生産されました。

于 2011-11-22T15:56:45.877 に答える
8

.Net4アセンブリでJerryCurrryのソリューションを使用しましたが、ビルドごとに異なる3番目の項目であるチェックサムがあることがわかりました。アセンブリ内にチェックサムを見つけるのは驚くべきことではありませんか?そのファイル内にファイルのチェックサムを追加すると、チェックサムが変更されると思います...

とにかく、変更されたコマンドは次のとおりです。

ildasm /all /text "assembly.dll"
| find /v "// Time-date stamp:"
| find /v "// MVID:"
| find /v "// Checksum:"
> assembly.dasm

意図しない一致を避けるために、スラッシュを追加して検索文字列も少し変更したことに注意してください。このコマンドの行は、読みやすくするために分割して、同じ行で一緒に実行する必要があります。ファイル名にスペースが含まれている場合は、ファイル名を二重引用符で囲む必要があります。

于 2011-05-19T08:01:14.897 に答える
3

MonoCecilを使用して、問題を解決するために小さな変更を加えることができます。私はそれをしました、あなたはここでその方法を読むことができます:http: //groups.google.com/group/mono-cecil/browse_thread/thread/6ab42df05daa3a/49e8b3b279850f13#49e8b3b279850f13

よろしくフロリアン

于 2011-06-18T22:02:30.917 に答える
3

実行する作業の量と、パフォーマンスや精度の重要性に応じて、いくつかの方法があります。Eric J. が指摘した 1 つの方法は、アセンブリをバイナリで比較し、コンパイルごとに変更される部分を除外することです。このソリューションは簡単で高速ですが、多くの偽陰性が発生する可能性があります。より良い方法の 1 つは、リフレクションを使用してドリルダウンすることです。パフォーマンスが重要な場合は、タイプを比較することから始めて、それらが一致する場合はメンバー定義に進みます。型とメンバーの定義を確認した後、すべてがその時点と等しい場合は、各メソッドの実際の IL を調べてさらに進むことができます。GetILAsByteArray方法。繰り返しになりますが、すべてが同じであるが、少し異なるフラグまたは異なるバージョンのコンパイラでコンパイルされている場合でも、違いが見つかります。最良の解決策は、ビルドにソース管理のチェンジセット番号をタグ付けする継続的インテグレーション ツールを使用することです (使用しているのですね?)。

関連記事

于 2010-05-31T01:03:16.383 に答える
1

ここでReflector Diff AddIn を使用できます。

于 2014-03-13T08:12:09.930 に答える
0

考慮すべき別の解決策:

バイナリがデバッグ モードでコンパイルされると、ソース コード情報が保存されます。次に、pdb が exe と一致するかどうか、および pdb 行がソース コードと一致するかどうかを確認できます。

于 2010-11-18T07:29:26.313 に答える