Подтвердить что ты не робот

Определите, были ли сборки .NET построены из одного источника

Кто-нибудь знает, как сравнить две сборки .NET, чтобы определить, были ли они созданы из "одинаковых" исходных файлов?

Я знаю, что есть некоторые доступные утилиты для разнесения, такие как плагин для Reflector, но мне не интересно просматривать различия в графическом интерфейсе, я просто хочу автоматизированный способ сравнить коллекцию двоичных файлов, чтобы узнать, были ли они построенных из тех же (или эквивалентных) исходных файлов. Я понимаю, что несколько разных исходных файлов могут создавать один и тот же IL и понимать, что процесс будет чувствителен только к различиям в IL, а не в исходном источнике.

Основным препятствием для простого сравнения потоков байтов для двух сборок является то, что .NET включает в себя поле под названием "MVID" (идентификатор версии модуля) сборки. Для каждой компиляции это значение имеет другое значение, поэтому, если вы создадите один и тот же код дважды, сборка будет отличаться.

Связанный вопрос: кто-нибудь знает, как заставить MVID быть одинаковым для каждой компиляции? Это позволит нам избежать процесса сравнения, который нечувствителен к различиям в значении MVID. Согласованный MVID был бы предпочтительнее, так как это означает, что могут использоваться стандартные контрольные суммы.

Основой этого является то, что сторонняя компания несет ответственность за независимое рассмотрение и отключение наших выпусков до того, как нам разрешат выпустить в Production. Это включает в себя проверку исходного кода. Они хотят самостоятельно подтвердить, что исходный код, который мы им даем, соответствует двоичным файлам, которые мы ранее построили, протестировали и в настоящее время планируем развернуть. Мы ищем процесс, который позволяет им самостоятельно строить систему из источника, который мы им поставляем, и сравнивать контрольные суммы с контрольными суммами для тестируемых двоичных файлов.

BTW. Обратите внимание, что мы используем непрерывную интеграцию, автоматические сборки, контроль источника и т.д. Проблема не связана с внутренним отсутствием контроля над исходными файлами в данной сборке. Проблема в том, что третья сторона несет ответственность за проверку того, что источник, который мы им предоставляем, производит те же бинарные файлы, которые мы тестировали, и планируем ввести в Production. Они не должны доверять ни одной из наших внутренних систем или элементов управления, включая сервер сборки или систему управления исходным кодом. Все, о чем они заботятся, это получение источника, связанного с сборкой, выполнение самой сборки и проверка того, что результаты соответствуют тому, что мы говорим, мы развертываем.

Скорость выполнения решения сравнения не имеет особого значения.

спасибо

4b9b3361

Ответ 1

Не слишком больно использовать инструменты командной строки для фильтрации MVID и меток даты-времени из текстового представления IL. Предположим, файлы file1.exe и file2.exe построены из тех же источников:

c:\temp > ildasm/all/text file1.exe | find/v "Дата штампа:" | find/v "MVID" > file1.txt

c:\temp > ildasm/all/text file2.exe | find/v "Дата штампа:" | find/v "MVID" > file2.txt

c:\temp > fc file1.txt file2.txt

Сравнение файлов file1.txt и FILE2.TXT

FC: не обнаружено различий

Ответ 2

Я использовал решение Джерри Керри на сборках .Net 4 и выяснил, что теперь есть третий элемент, который будет отличаться для каждой сборки: контрольная сумма. Разве не удивительно находить контрольную сумму внутри сборки? Я думаю, что добавление контрольной суммы файла внутри этого файла изменит контрольную сумму...

В любом случае, измененная команда:

ildasm /all /text "assembly.dll"
| find /v "// Time-date stamp:"
| find /v "// MVID:"
| find /v "// Checksum:"
> assembly.dasm

Обратите внимание, что я также немного изменил строки поиска, добавив косые черты, чтобы избежать непреднамеренных совпадений. Строки этой команды должны запускаться вместе в одной строке, разделенной на читаемость. Имена файлов будут содержать двойные кавычки, если они содержат пробелы.

Ответ 3

При сравнении библиотек классов с ILDasm v4.0.319.1 кажется, что база изображений не инициализирована. Чтобы избежать несоответствий, используйте пересмотренное решение:

ildasm /all /text assembly.dll
| find /v "// Time-date stamp:"
| find /v "// MVID:"
| find /v "// Checksum:"
| find /v "// Image base:"
> assembly.dasm

Точка входа (база изображений) - фактически интересная информация для исполняемых сборок и должна быть проверена тщательно. Внедрение новой базы изображений - это общий способ сделать программу чем-то совершенно другим. В моем случае я пытаюсь проверить согласованность многопоточных сборников, поэтому безопасно пропустить точку входа.

Заметка о производительности: я взял 8 МБ DLL, которая была построена для AnyCPU, и запускала ILDasm. Результирующий файл был размером 251 МБ и потребовалось несколько минут. Примерно в 32 раза был произведен размер.

Ответ 4

Есть несколько способов сделать это в зависимости от объема работы, которую вы готовы сделать, и важности производительности и/или точности. Один из способов, как указал Эрик Дж., - сравнить сборки в двоичном формате, исключая части, которые изменяются при каждой компиляции. Это решение легко и быстро, но может дать вам много ложных негативов. Один лучший способ - развернуть, используя отражение. Если производительность критическая, вы можете начать с сравнения типов и, если они совпадают, перейти к определениям членов. После проверки определений типов и членов, и если все будет равно этой точке, вы можете пойти дальше, исследуя фактический IL каждого метода, пройдя его через метод GetILAsByteArray. Опять же, вы найдете различия, даже если все одно и то же, но скомпилировано с помощью немного разных флагов или другой версии компилятора. Я бы сказал, что лучшим решением является использование инструментов непрерывной интеграции, которые маркируют сборку с номером набора изменений вашего исходного элемента управления (вы используете один, правильно?).

Связанная статья

Ответ 6

Вы можете использовать Reflector Diff AddIn здесь.

Ответ 7

Другое решение:

Информация о исходном коде сохраняется при компиляции двоичных файлов в режиме отладки. Затем вы можете проверить, соответствует ли pdb exe, и если строки pdb соответствуют исходному коду.