2010-07-23 18 views
7

Ho creato una semplice applicazione "Hello World" in VS2005. È un'applicazione console diretta; contiene solo le righe seguenti:Come posso sapere se un "assemblaggio" è davvero cambiato?

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

Quando ho cercato di ricostruire la stessa applicazione console senza eseguire alcuna modifica (basta premere il pulsante ricostruire), ottengo un eseguibile leggermente diverso. (Ho generato un hash SHA-1 sia dal 1 ° che dal 2 ° generato ed è diverso!)

Perché è diverso quando non ci sono modifiche al codice? Cosa è effettivamente cambiato? Ho usato un editor esadecimale per confrontare e ho visto solo un paio di byte diversi.

Credo che la mia ultima domanda sia, come faccio a sapere se un "assemblaggio" è davvero cambiato? (Naturalmente, senza guardare le versioni del file, dimensione del file, ecc)

EDIT

Finora, abbiamo stabilito che la differenza sta nell'intestazione PE (timestamp e alcuni dati di debug). Prima di re-inventare la ruota, c'è uno strumento di "confronto di assieme" che ignora l'intestazione PE?

Grazie, Ian

risposta

6

Le differenze saranno

  • il timestamp nell'intestazione PE
  • la GUID dei dati di debug, se presenti

(e forse qualcosa di più, come per l'altro output che hai postato?) Per vederli, eseguire dumpbin /all /rawdata:none su entrambi gli assiemi in un prompt dei comandi VS.

Per fare ciò correttamente, dovresti scrivere uno strumento di confronto che capisca questo e ignori quei byte - o abbia preso copie degli eseguibili, cancellato il timestamp e il GUID e poi confrontato quelle versioni. Oppure, a un certo punto, è possibile utilizzare qualcosa come fc /b come suggerisce controlfreak e assumere che se ci sono < 20 byte diversi (4 per il timestamp, 16 per il GUID), allora è probabilmente lo stesso.

Si può tranquillamente usare un assembly con il timestamp azzerato - AFAIK è usato solo per memorizzare gli offset di simboli esportati in altre DLL se lo si collega - ma probabilmente è più sicuro andarsene così com'è. Se hai effettivamente bisogno di assembly binari-identici, ti suggerisco di cambiare i tuoi processi in modo da non pulire mai, a meno che tu non ne abbia davvero bisogno.

+0

Per ignorare correttamente quei byte, ho bisogno di sapere la posizione e l'intervallo di quei byte giusto? C'è una documentazione di qualche tipo che posso leggere? – Ian

+0

Ecco il collegamento alla documentazione in formato PE da MSDN: http://www.microsoft.com/whdc/system/platform/firmware/PECOFF.mspx Intendevo il timestamp nell'intestazione COFF e il contenuto della directory di debug. Tuttavia sarei molto sorpreso se gli strumenti per farlo non esistessero già - ma non ne conosco uno, mi dispiace. – Rup

+0

Wow, l'hai inchiodato. È il timestamp e alcuni dati di debug! 4C4953A4 data ora timbro ven lug 23 16:32:36 2010 4C4953A4 cv 6D 000026E4 8E4 Formato: RSDS, {F421268D-98D4-4D76-B70D-9C3E398E5426}, 1, C: \ HelloWorld \ HelloWorld \ obj \ x86 \ Debug \ HelloWorld.pdb * utilizzando dumpbin/all/rawdata: none – Ian

0

Sulla riga comandi fc/b < vecchiofile> < newfile>

+1

Questo dovrebbe essere una risposta? Fornisci almeno un contesto. – Oded

+0

haha ​​mi dispiace. Ho messo alcune cose tra parentesi ed è pensato che fossero i tag html –

+0

file Confrontando a.exe e b.exe 00.000.088: 92 A4 00.000.770: F4 DD 00.000.771: 62 20 00.000.772: 7F CF 00.000.773: A1 24 00.000.774 : 0B AA 00.000.775: 5A 16 00.000.776: 7A 9A 00.000.777: 43 41 00.000.778: B7 9D 00.000.779: 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: E0 3E 000008F4: 4D 39 000008F5: 83 8E 000008F6: 6E 54 000008F7: 1E 26 000008F8: 02 01 – Ian

2

da un comando di Visual Studio chiede conferma che si può fare un confronto più elaborato:

  • si potrebbe paragonare l'intestazione PE utilizzando l'uscita di dumpbin:

    dumpbin /HEADERS assembly.dll 
    
  • Oppure si potrebbe confrontare PE intestazioni e il codice IL incorporato nell'assieme utilizzando ildasm:

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

    L'opzione /ALL eseguirà il dump delle intestazioni DOS e PE, dell'intestazione CLR, dei metadati dell'assieme e dell'IL disassemblato. Tuttavia, non conterrà risorse incorporate. Se il gruppo di installazione contiene risorse incorporate, è possibile utilizzare l'opzione /OUT. Questo creerà un file separato per ciascuna risorsa incorporata che puoi confrontare usando il tuo strumento diff preferito, ad es. WinMerge:

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