2010-07-23 12 views
7

J'ai créé une simple application "Hello World" dans VS2005. C'est une application de console directe; il ne contient que les lignes suivantes:Comment puis-je savoir si un "assemblage" a vraiment changé?

Console.WriteLine("Hello World"); 
Console.ReadLine(); 

Quand j'ai essayé de reconstruire la même application de la console sans effectuer des modifications (il suffit d'appuyer sur le bouton reconstruction), je reçois un exécutable subtilement différent. (J'ai généré un hachage SHA-1 à partir du 1er et du 2ème exécutable généré, et c'est différent!)

Pourquoi est-ce différent quand il n'y a pas de changement de code? Qu'est-ce qui a vraiment changé? J'ai utilisé un éditeur hexadécimal pour comparer et n'a vu que quelques octets différents.

Je suppose que ma question ultime est, comment puis-je savoir si un "assemblage" a réellement changé? (Bien sûr, sans regarder les versions de fichier, la taille du fichier, etc.)

EDIT

Jusqu'à présent, nous avons établi que la différence réside dans l'en-tête PE (horodatage et des données de débogage). Avant de réinventer la roue, existe-t-il un outil de "comparaison d'assemblage" qui ignore l'en-tête PE?

Merci, Ian

Répondre

6

Les différences seront

  • l'horodatage dans l'en-tête PE
  • la GUID des données de débogage, si présentes

(et peut-être quelque chose de plus, selon l'autre sortie que vous avez publiée?) Pour les voir, exécutez dumpbin /all /rawdata:none sur les deux assemblys dans une invite de commande VS. Pour faire cela correctement, vous devez écrire un outil de comparaison qui a compris cela et ignoré ces octets - ou pris des copies des exécutables, effacé l'horodatage et le GUID, puis comparé ces versions. Ou, à la rigueur, vous pouvez utiliser quelque chose comme fc /b comme le suggère controlfreak et supposer que s'il y a < 20 octets différents (4 pour l'horodatage, 16 pour le GUID) alors c'est probablement pareil. Vous pouvez très bien utiliser un assembly avec l'horodatage effacé - AFAIK il est seulement utilisé pour mettre en mémoire cache les décalages de symbole exportés dans d'autres DLL si vous le reliez, mais il est probablement plus sûr de le laisser tel quel. Si vous avez réellement besoin d'assemblages binaires identiques, je vous suggère de changer vos processus afin de ne jamais les nettoyer, sauf si vous en avez vraiment besoin.

+0

Afin d'ignorer correctement ces octets, j'ai besoin de connaître l'emplacement et la portée de ces octets non? Y a-t-il une documentation que je puisse lire? – Ian

+0

Voici le lien de la documentation au format PE de MSDN: http://www.microsoft.com/whdc/system/platform/firmware/PECOFF.mspx Je voulais dire l'horodatage dans l'en-tête COFF et le contenu du répertoire de débogage. Cependant, je serais très surpris si les outils pour le faire n'existent pas déjà - mais je n'en connais pas un, désolé. – Rup

+0

Wow, vous l'avez cloué. C'est l'horodatage et quelques données de débogage! 4C4953A4 horodatage Fri Jul 23 16:32:36 2010 4C4953A4 cv 6D 000026E4 8E4 Format: RSDS, {F421268D-98D4-4D76-B70D-9C3E398E5426}, 1, C: \ HelloWorld \ HelloWorld \ obj \ x86 \ Déboguer \ HelloWorld.pdb * en utilisant dumpbin/all/rawdata: none – Ian

0

Sur la ligne de commande fc/b < oldfile> < newfile>

+1

Est-ce censé être une réponse? Au moins fournir un contexte. – Oded

+0

haha ​​désolé. Je mets des choses entre parenthèses et pensé qu'ils étaient des balises html –

+0

Comparaison de fichiers a.exe et b.exe 00000088: 92 A4 00000770: F4 DD 00000771: 62 20 00000772: 7F CF 00000773: A1 24 00000774 : 0B AA 00000775: 5A 16 00000776: 7A 9A 00000777: 43 41 00000778: B7 9D 00000779: F3 39 0000077A: 22 C0 0000077B: 8D BF 0000077C: 50 82 0000077D: 17 1D 0000077E : 52 27 0000077F: D6 4A 000008CC: 92 A4 000008E8: 2A 8D 000008E9: 6D 26 000008EA: C2 21 000008EB: F0 F4 000008EC: 70 D4 000008ED: 1E 98 000008EE: 3F 76 000008EF: 4B 4D 000008F0: AC B7 000008F1: 5A 0D 000008F2: 75 9C 000008F3: 3E 000008F4 E0: 4D 39 000008F5: 83 8E 000008F6: 6E 54 000008F7: 1E 26 000008F8: 02 01 – Ian

2

D'un, vous pouvez invite de commande Visual Studio faire une comparaison plus élaborée:

  • Vous pouvez comparer l'en-tête de PE en utilisant la sortie de dumpbin:

    dumpbin /HEADERS assembly.dll 
    
  • Ou vous pouvez comparer PE en-têtes et le code IL incorporé dans l'ensemble en utilisant ildasm:

    ildasm /ALL /TEXT assembly1.dll > dump1.txt 
    ildasm /ALL /TEXT assembly2.dll > dump2.txt 
    fc dump1.txt dump2.txt   
    

    L'option /ALL va vider les en-têtes DOS et PE, l'en-tête CLR, les métadonnées d'assemblage et l'unité d'assemblage désassemblée. Cependant, il ne contiendra pas de ressources intégrées. Si votre assmembly contient des ressources incorporées, vous pouvez utiliser l'option /OUT. Cela créera un fichier distinct pour chaque ressource incorporée que vous pouvez comparer à l'aide de votre outil de comparaison préféré, par ex. WinMerge:

    ildasm /ALL /TEXT /OUT:folder1\dump.txt folder1\assembly.dll 
    ildasm /ALL /TEXT /OUT:folder2\dump.txt folder2\assembly.dll