5

複数のリリースを経たバージョン管理下にあるプログラムがあります。今日、誰かがどうにかしてプログラムの古いコピーを指摘し、その後修正されたバグに遭遇したという状況が発生しました。戻って、プログラムの古いコピーをすべて削除したいのですが (バージョン管理が一般的になる前から、それらを保持することは会社のポリシーであり、もはや必要ではありません)、それができることを確認する方法が必要です。 「古いものはこのコミットから出てきたので、これは同じはずです」と言うよりも優れた、まったく同じ実行可能ファイルを生成します。

私の最初の考えは、単純に実行可能ファイルを MD5 ハッシュし、ハッシュ ファイルをソース管理に保存して、それを処理することでしたが、解析することさえできない問題に遭遇しました。

実行可能ファイルが生成されるたびに (方法: Open Project. File > Make X.exe)、ハッシュが異なるようです。プロジェクトが一見ランダムな方法で開かれるたびに、Visual Basic がファイルを混乱させることに気付きましたが、それが実行可能ファイルに組み込まれるとは思いませんでした。また、それが実際に起こっているという証拠もありません。それを防ぐために、同じIDEセッション内で実行可能ファイルを複数回生成し、ハッシュをチェックしようとしましたが、毎回異なっていました。

だから〜だ:

  1. 実行可能ファイルを生成
  2. MD5 チェックサムを生成します。md5sum X.exe > X.md5
  3. 現在の実行可能ファイルの MD5 を確認します。md5sum -c X.md5
  4. 新しい実行可能ファイルを生成
  5. 新しい実行可能ファイルの MD5 を確認します。md5sum -c X.md5
  6. 計算されたチェックサムが一致しないため、検証に失敗します。

MD5またはVB 6が実行可能ファイルを生成する方法について何かを理解していませんが、MD5を使用するという考えにも結婚していません。2 つの実行可能ファイルが実際に同じであることを確認するためのより良い方法があれば、私は耳を傾けます。

よろしくお願いします。

4

2 に答える 2

13

それはほぼ不可能でしょう。その理由を読んでください。

コンパイラは毎回このゲームに勝つでしょう...

ソース コードやプロジェクト設定を変更しなくても、同じプロジェクトを 2 回続けてコンパイルすると、常に異なる実行可能ファイルが生成されます。

この理由の 1 つは、Windows が EXE ファイルに使用する PE (Portable Executable) 形式に、EXE がビルドされた日時を示すタイムスタンプが含まれていることです。このタイムスタンプは、プロジェクトをビルドするたびに VB6 コンパイラによって更新されます。EXE 全体の「メイン」タイムスタンプに加えて、EXE 内の各リソース ディレクトリ (アイコン、ビットマップ、文字列などが EXE に格納されている場所) にもタイムスタンプがあり、コンパイラは新しいリソースをビルドするときにもタイムスタンプを更新します。 EXE。これに加えて、EXE ファイルには、コンパイラが EXE の生のバイナリ コンテンツに基づいて再計算するチェックサム フィールドもあります。タイムスタンプは現在の日付/時刻に更新されるため、プロジェクトが再コンパイルされるたびに EXE のチェックサムも変更されます。

しかし、しかし...私は、このコンパイラのトリックを元に戻すことができる、この本当にクールなEXE編集ツールを見つけました!

PE Explorerなどの EXE 編集ツールがあり、EXE ファイル内のすべてのタイムスタンプを固定時間に調整できると主張しています。一見すると、EXE の 2 つのコピーのタイムスタンプを同じ日付に設定するだけで、最終的に同等のファイルが得られると思うかもしれません (それらが同じソース コードからビルドされたと仮定して)。しかし、事態はそれよりも複雑です。コンパイラは、コードをコンパイルするたびにリソース (文字列、アイコン、ファイルのバージョン情報など) を自由に書き出すことができますが、これを防ぐことはできません。リソースは、プログラムの実行時の動作に影響を与えることなく、結果の EXE で再配置できるデータの独立した「チャンク」として格納されます。

それだけでは不十分な場合、コンパイラは初期化されていないメモリ領域に EXE ファイルを構築している可能性があるため、EXE の特定の部分には、コンパイラの実行時にメモリ内にあったものの断片が含まれ、さらに多くのファイルが作成される可能性があります。違い。

MD5に関しては...

MD5 ハッシュを誤解しているのではありません。MD5 は、同じ入力に対して常に同じハッシュを生成します。ここでの問題は、この場合の入力 (EXE ファイル) が変化し続けることです。

結論: ソース管理はあなたの味方です

あなたの現在のジレンマを解決するために、私はあなたにこれを残します.特定のEXEを特定のバージョンのソースコードに関連付けることは、何よりもポリシーの問題であり、何らかの方法で強制する必要があります. 何のコンテキストもなしに、どの EXE がどのバージョンから来たのかを把握しようとしても、信頼できません。他のツールを使用してこれを追跡する必要があります。たとえば、ビルドごとに EXE の異なるバージョン番号が生成されるようにし、そのバージョンをバージョン管理システムの特定のリビジョン/ブランチ/タグなどと簡単に組み合わせることができるようにします。そのために、一部の開発者はソース管理を使用し、他の開発者は「1997 年のソース コードのコピーをネットワーク フォルダーに保管しているが、これは私のコードであるため、そのコピーを使用する」という「誰でも自由」な状況です。とにかく、ソース管理は弱虫のためのものです」ということは、これを簡単にするのに役立ちません。ソース管理のクールエイドを飲んで、すぐにビルドを作成するための標準ポリシーを順守してもらいます。

プロジェクトをビルドするときはいつでも、ビルド サーバー ( Hudsonを使用) によって、コンパイルされた EXE バージョンが更新され、現在のビルド番号が含まれるようになります (バージョン番号プラグインとカスタム ビルド スクリプトを使用してこれを行います)。 、バージョン番号をタグ名として使用して Subversion でタグを作成します。ビルド サーバーはリリース ビルドをアーカイブするため、お客様に提供された特定の EXE (およびセットアップ プログラム) をいつでも取得できます。内部テストでは、アーカイブされた EXE をビルド サーバーからプルするか、Subversion で作成したタグから EXE を再構築するようにビルド サーバーに指示するかを選択できます。

また、ビルド サーバー以外のマシンからバイナリを QA や顧客にリリースすることは決してありません。これにより、「自分のマシンで動作する」バグが防止され、常にソース コードの「既知の」コピーからコンパイルされ (Subversion リポジトリにあるコードのみをプルしてビルドする)、特定の作成元のコードの正確なバージョンのバイナリ。

于 2010-05-15T08:26:04.737 に答える