5 Stimmen

Wie überprüfen Sie, dass 2 Kopien eines VB 6-Programms aus dem gleichen Code stammen?

Ich habe ein Programm unter Versionskontrolle, das mehrere Veröffentlichungen durchlaufen hat. Heute ist eine Situation aufgetreten, bei der jemand anscheinend auf eine alte Kopie des Programms verwiesen hat und somit auf Fehler stieß, die inzwischen behoben wurden. Ich möchte zurückgehen und einfach alle alten Kopien des Programms löschen (das Aufbewahren ist eine Unternehmensrichtlinie, die vor der gängigen Versionskontrolle stammt und nicht mehr erforderlich sein sollte), aber ich brauche eine Möglichkeit zu überprüfen, dass ich die genau gleiche ausführbare Datei erstellen kann, die besser ist als zu sagen "Die alte stammt aus diesem Commit, also sollte diese dieselbe sein."

Mein erster Gedanke war einfach, die MD5-Prüfsumme der ausführbaren Datei zu erstellen, die Hash-Datei in der Quellkontrolle zu speichern und fertig damit zu sein, aber ich bin auf ein Problem gestoßen, das ich nicht einmal analysieren kann.

Es scheint, dass jedes Mal, wenn die ausführbare Datei erstellt wird (Methode: Projekt öffnen. Datei > X.exe erstellen), sich der Hash unterscheidet. Ich habe bemerkt, dass Visual Basic Dateien jedes Mal manipuliert, wenn das Projekt auf scheinbar zufällige Weise geöffnet wird, aber ich dachte nicht, dass es in die ausführbare Datei gelangen würde, noch habe ich Beweise dafür, dass dies tatsächlich passiert. Um dagegen vorzugehen, habe ich versucht, die ausführbare Datei mehrmals in derselben IDE-Sitzung zu erstellen und die Hashes zu überprüfen, aber sie waren jedes Mal unterschiedlich.

Also das:

  1. Ausführbare Datei erstellen
  2. MD5-Prüfsumme erstellen: md5sum X.exe > X.md5
  3. MD5 für aktuelle ausführbare Datei überprüfen: md5sum -c X.md5
  4. Neue ausführbare Datei erstellen
  5. MD5 für neue ausführbare Datei überprüfen: md5sum -c X.md5
  6. Überprüfung fehlgeschlagen, weil die berechnete Prüfsumme nicht übereinstimmt.

Ich verstehe etwas entweder nicht über MD5 oder die Art und Weise, wie VB 6 die ausführbare Datei erstellt, aber ich bin auch nicht auf die Idee festgelegt, MD5 zu verwenden. Wenn es einen besseren Weg gibt, zu überprüfen, dass zwei ausführbare Dateien tatsächlich identisch sind, bin ich ganz Ohr.

Vielen Dank im Voraus für deine Hilfe!

13voto

Mike Spross Punkte 7801

Das wird fast unmöglich sein. Lesen Sie weiter, um zu erfahren warum.

Der Compiler gewinnt jedes Mal dieses Spiel...

Wenn das gleiche Projekt hintereinander zweimal kompiliert wird, auch wenn keine Änderungen am Quellcode oder den Projekteinstellungen vorgenommen wurden, werden immer unterschiedliche ausführbare Dateien erstellt.

Ein Grund dafür ist, dass das PE (Portable Executable) Format, das Windows für EXE-Dateien verwendet, einen Zeitstempel enthält, der das Datum und die Uhrzeit angibt, an denen die EXE erstellt wurde. Dieser Zeitstempel wird vom VB6-Compiler aktualisiert, wenn das Projekt kompiliert wird. Neben dem "Haupt" Zeitstempel für die gesamte EXE hat jeder Ressourcenverzeichnis in der EXE (wo Symbole, Bitmaps, Zeichenfolgen usw. in der EXE gespeichert sind) auch einen Zeitstempel, den der Compiler aktualisiert, wenn eine neue EXE erstellt wird. Darüber hinaus haben EXE-Dateien auch ein Prüfsummenfeld, das der Compiler aufgrund des rohen binären Inhalts der EXE neu berechnet. Da die Zeitstempel auf das aktuelle Datum/Uhrzeit aktualisiert werden, ändert sich auch die Prüfsumme für die EXE jedes Mal, wenn ein Projekt neu kompiliert wird.

Aber...ich habe dieses wirklich coole EXE-Bearbeitungstool gefunden, das diese Compiler-Täuschung rückgängig machen kann!

Es gibt EXE-Bearbeitungstools wie PE Explorer, die behaupten, alle Zeitstempel in einer EXE-Datei auf eine feste Zeit einstellen zu können. Auf den ersten Blick könnten Sie denken, dass Sie einfach die Zeitstempel in zwei Kopien der EXE auf das gleiche Datum setzen könnten und äquivalente Dateien erhalten (vorausgesetzt, sie wurden aus dem gleichen Quellcode erstellt), aber die Dinge sind komplizierter: Der Compiler schreibt die Ressourcen (Zeichenfolgen, Symbole, Dateiversion Informationen usw.) jedes Mal in einer anderen Reihenfolge, wenn der Code kompiliert wird, und das können Sie nicht wirklich verhindern. Ressourcen werden als unabhängige "Chunks" von Daten gespeichert, die im resultierenden EXE neu angeordnet werden können, ohne das Laufzeitverhalten des Programms zu beeinflussen.

Wenn das nicht genug wäre, könnte der Compiler die EXE-Datei in einem Bereich nicht initialisierten Speichers erstellen, sodass bestimmte Teile der EXE Bits und Stücke von dem enthalten können, was zum Zeitpunkt des Kompilierens im Speicher war, was noch mehr Unterschiede schafft.

Betrachtung von MD5...

Sie haben das MD5-Hashing nicht falsch verstanden: MD5 wird immer bei gleicher Eingabe den gleichen Hash-Wert erzeugen. Das Problem hier ist jedoch, dass die Eingabe in diesem Fall (die EXE-Dateien) sich ständig ändert.

Fazit: Die Quellcodeverwaltung ist dein Freund

Um Ihr aktuelles Dilemma zu lösen, möchte ich Sie damit lassen: Die Zuordnung einer bestimmten EXE zu einer bestimmten Version des Quellcodes ist eher eine Angelegenheit der Richtlinie, die irgendwie durchgesetzt werden muss, als alles andere. Zu versuchen herauszufinden, welche EXE aus welcher Version stammt, ohne jeglichen Kontext, wird einfach nicht zuverlässig sein. Sie müssen dies mithilfe anderer Tools verfolgen. Beispielsweise können Sie sicherstellen, dass jede Erstellung eine andere Versionsnummer für Ihre EXE's erzeugt und dass diese Version einfach mit einer bestimmten Revision/Verzweigung/Markierung/whatever in Ihrem Versionsverwaltungssystem verknüpft werden kann. Zu diesem Zweck wird eine "Freifluss"-Situation, in der einige Entwickler die Quellcode-Verwaltung nutzen und andere "diese Kopie des Quellcodes von 1997, die ich in meinem Netzwerkordner aufbewahre, benutzen, weil es mein Code ist und Quellcodeverwaltung sowieso für Weicheier ist", dieses Problem nicht erleichtern. Ich würde jedem nahelegen, den Quellcode-Kool-Aid zu trinken und sich sofort an eine standardmäßige Richtlinie zur Erstellung von Builds zu halten.

Immer wenn wir Projekte erstellen, stellt unser Build-Server (wir verwenden Hudson) sicher, dass die kompilierte EXE-Version aktualisiert wird, um die aktuelle Build-Nummer einzuschließen (wir verwenden das Version Number Plugin und ein individuelles Build-Skript, um dies zu tun), und wenn wir einen Build veröffentlichen, erstellen wir einen Tag in Subversion mit dem Versionsnamen als Tag-Namen. Der Build-Server archiviert Freigabe-Builds, sodass wir immer die spezifische EXE (und das Setup-Programm) erhalten können, das einem Kunden gegeben wurde. Für interne Tests können wir wählen, eine archivierte EXE vom Build-Server abzurufen oder einfach den Build-Server auffordern, die EXE aus dem Tag, den wir in Subversion erstellt haben, neu zu erstellen.

Wir veröffentlichen auch niemals Binärdateien an QA oder an Kunden von einem anderen Computer als dem Build-Server aus. Dies verhindert "funktioniert auf meinem Computer" -Bugs und stellt sicher, dass wir immer von einer "bekannten" Kopie des Quellcodes kompilieren (es zieht und baut nur Code, der sich in unserem Subversion-Repository befindet) und dass wir immer eine bestimmte Binärdatei mit der genauen Version des Codes in Verbindung bringen können, aus der sie erstellt wurde.

0voto

TAbdiukov Punkte 1164

Ich weiß, es ist schon eine Weile her, aber da es eine VB De-Compiler-App gibt, könnten Sie in Betracht ziehen, VB6-Apps massenweise zu dekompilieren und dann die Dekompilierungsergebnisse an eine KI/statistische Anomalieerkennung auf den verschiedenen Code-Basen zu übergeben. Angesichts des Problems, mit dem Sie konfrontiert sind, keine exakte Lösung haben, ist es unwahrscheinlich, dass die Ergebnisse zu 100% genau sind, aber je mehr Daten Sie einspeisen, desto genauer sollte die Erkennung werden

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X