Как я могу знать, изменялся ли “блок” действительно?

Я создал простое "Привет Мировое" приложение в VS2005. Это - простое консольное приложение; это только содержит следующие строки:

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

Когда я пытался восстановить то же консольное приложение, не выполняя изменений (просто нажимают восстановить кнопку), я получаю тонко другой исполняемый файл. (Я генерировал хеш SHA-1 и от 1-го и от 2-го сгенерированного исполняемого файла, и это отличается!)

Почему это отличается, когда нет никаких изменений кода? Что на самом деле изменилось? Я использовал Hex-редактор для сравнения и только видел пару различных байтов.

Я предполагаю, что мой окончательный вопрос, как я могу знать, изменялся ли "блок" действительно? (Конечно, не смотря на Версии файла, размер файла, и т.д.)

Править

До сих пор мы установили, что различие заключается в заголовке PE (метка времени и некоторые отладочные данные). Прежде чем я изобрету велосипед, существует ли "инструмент" сравнения блока, который игнорирует заголовок PE?

Спасибо, Ian

7
задан Ian 23 July 2010 в 08:54
поделиться

3 ответа

Различия будут заключаться в

  • метке времени в заголовке PE
  • GUID отладочных данных, если они присутствуют

(и, возможно, что-то еще, согласно другим данным, которые вы выложили?) Чтобы увидеть их, запустите dumpbin /all /rawdata:none на обеих сборках в командной строке VS.

Чтобы сделать это правильно, вам придется написать инструмент сравнения, который понимает это и игнорирует эти байты - или сделать копии исполняемых файлов, очистить метку времени и GUID, а затем сравнить эти версии. Или, в крайнем случае, можно использовать что-то вроде fc /b, как предлагает controlfreak, и считать, что если разница в байтах < 20 (4 для временной метки, 16 для GUID), то это, вероятно, одно и то же.

Вы вполне можете обойтись использованием сборки с очищенной меткой времени - AFAIK она используется только для кэширования смещений экспортируемых символов в других DLL, если вы подключите их - но, вероятно, безопаснее оставить все как есть. Если вам действительно нужны двоично-идентичные сборки, я предлагаю изменить ваши процессы так, чтобы вы никогда не выполняли clean-build, если только вам это действительно не нужно.

6
ответ дан 7 December 2019 в 05:16
поделиться

В командной строке fc /b < oldfile > < newfile >

0
ответ дан 7 December 2019 в 05:16
поделиться

Из командной строки Visual Studio вы можете сделать более детальное сравнение:

  • Вы можете сравнить PE заголовок, используя вывод dumpbin:

    dumpbin /HEADERS assembly.dll
    
  • Или вы можете сравнить PE-заголовки и IL-код, встроенный в сборку, используя ildasm:

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

    Опция /ALL приведет к дампу заголовков DOS и PE, заголовка CLR, метаданных сборки и дизассемблированного IL. Однако он не будет содержать встроенных ресурсов. Если ваша сборка содержит встроенные ресурсы, вы можете использовать опцию /OUT. Это создаст отдельный файл для каждого встроенного ресурса, который вы можете сравнить с помощью вашего любимого инструмента сравнения, например, WinMerge:

    ildasm /ALL /TEXT /OUT:folder1\dump.txt folder1\assembly.dll
    ildasm /ALL /TEXT /OUT:folder2\dump.txt folder2\assembly.dll
    
2
ответ дан 7 December 2019 в 05:16
поделиться
Другие вопросы по тегам:

Похожие вопросы: