Как вы проверяете, что 2 копии исполняемого файла VB 6 пришли из одной и той же кодовой базы?

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

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

Кажется, что каждый раз, когда создается исполняемый файл (метод: Open Project. File > Make X.exe), он хэшируется по-разному. Я заметил, что Visual Basic портит файлы каждый раз, когда проект открывается случайным образом, но я не думал, что это превратится в исполняемый файл, и у меня нет никаких доказательств того, что это действительно происходит. Чтобы попытаться защититься от этого, я попытался сгенерировать исполняемый файл несколько раз в течение одного сеанса IDE и проверять хэши, но они продолжали каждый раз отличаться.

Так вот:

  1. Создать исполняемый файл
  2. Создать контрольную сумму MD5: md5sum X.exe > X.md5
  3. Проверьте MD5 для текущего исполняемого файла: md5sum -c X.md5
  4. Создать новый исполняемый файл
  5. Проверьте MD5 для нового исполняемого файла: md5sum -c X.md5
  6. Ошибка проверки, поскольку вычисленная контрольная сумма не совпадает.

Я ничего не понимаю ни в MD5, ни в том, как VB 6 генерирует исполняемый файл, но я также не женат на идее использования MD5. Если есть лучший способ проверить, что два исполняемых файла действительно одинаковы, тогда я весь слух.

Заранее спасибо за помощь!

1 ответ

Решение

Это будет почти невозможно. Продолжайте читать, почему.

Компилятор выиграет эту игру, каждый раз...

Компиляция одного и того же проекта два раза подряд, даже без внесения каких-либо изменений в исходный код или настройки проекта, всегда будет приводить к разным исполняемым файлам.

Одна из причин этого заключается в том, что формат PE (Portable Executable), который Windows использует для EXE-файлов, включает в себя временную метку, указывающую дату и время создания EXE-файла, которая обновляется компилятором VB6 при каждом построении проекта. Помимо "основной" временной метки для EXE-файла в целом, каждый каталог ресурсов в EXE-файле (где в EXE-файле хранятся значки, растровые изображения, строки и т. Д.) Также имеет временную метку, которую компилятор также обновляет при создании новой версии. EXE. В дополнение к этому EXE-файлы также имеют поле контрольной суммы, которое компилятор пересчитывает на основе необработанного двоичного содержимого EXE-файла. Поскольку метки времени обновляются до текущей даты / времени, контрольная сумма для EXE также будет меняться при каждой перекомпиляции проекта.

Но, но... Я нашел этот действительно крутой инструмент для редактирования EXE, который может отменить эту хитрость компилятора!

Существуют инструменты редактирования EXE, такие как PE Explorer, которые утверждают, что могут устанавливать все временные метки в файле EXE на фиксированное время. На первый взгляд вы можете подумать, что можете просто установить временные метки в двух копиях EXE на одну и ту же дату и получить эквивалентные файлы (при условии, что они были созданы из одного и того же исходного кода), но все сложнее: Компилятор может свободно записывать ресурсы (строки, значки, информацию о версии файла и т. д.) каждый раз, когда вы компилируете код, и вы не можете предотвратить это. Ресурсы хранятся в виде независимых "кусочков" данных, которые можно переставить в результирующем EXE-файле, не влияя на поведение программы во время выполнения.

Если этого недостаточно, возможно, компилятор создает файл EXE в области неинициализированной памяти, поэтому некоторые части EXE могут содержать кусочки того, что было в памяти во время работы компилятора, создавая еще больше различия.

Что касается MD5...

Вы не ошибаетесь в понимании хеширования MD5: MD5 всегда будет выдавать один и тот же хеш при одном и том же вводе. Проблема здесь в том, что входные данные в этом случае (файлы EXE) постоянно меняются.

Вывод: контроль источников - ваш друг

Что касается решения вашей текущей дилеммы, я оставлю вас с этим: ассоциирование конкретного EXE-файла с конкретной версией исходного кода - это больше вопрос политики, который должен быть как-то реализован, чем что-либо еще. Попытка выяснить, какой EXE-файл пришел из какой версии без какого-либо контекста, просто не будет надежной. Вы должны отслеживать это с помощью других инструментов. Например, убедитесь, что каждая сборка создает свой номер версии для вашего EXE-файла, и что эта версия может быть легко сопряжена с определенной ревизией / branch / tag / что угодно в вашей системе управления версиями. С этой целью в "бесплатной для всех" ситуации, когда некоторые разработчики используют контроль исходного кода, а другие используют "ту копию исходного кода 1997 года, которую я храню в своей сетевой папке, потому что это мой код и контроль исходного кода, предназначен для сестренок". во всяком случае "не поможет сделать это легче. Я хотел бы, чтобы все пили исходную версию Kool-Aid и сразу же придерживались стандартной политики создания сборок.

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

Мы также никогда не выпускаем двоичные файлы для QA или для клиентов с любого компьютера, кроме сервера сборки. Это предотвращает ошибки "работает на моей машине" и гарантирует, что мы всегда компилируем из "известной" копии исходного кода (он только извлекает и строит код, который находится в нашем хранилище Subversion), и что мы всегда можем связать данный двоичный файл с точной версией кода, из которого он был создан.

Я знаю, что прошло некоторое время, но, поскольку существует приложение VB De-compiler, вы можете рассмотреть возможность массовой декомпиляции приложений vb6, а затем передать результаты декомпиляции для обнаружения AI/ статистических аномалий на различных базах кода. Учитывая, что проблема, с которой вы сталкиваетесь, не имеет точного решения, маловероятно, что результаты будут точными на 100%, но по мере того, как вы вводите больше данных, обнаружение должно становиться все более и более точным.

Другие вопросы по тегам