Недавно я обнаружил отличное расширение Visual Studio, которое находит ненужные операторы #include в проектах и удаляет их. Я работаю над каким-то грубым устаревшим кодом, и он очень сильно удален. Единственная проблема в том, что я не могу быть уверен, что это не изменило сборку каким-то тонким образом. Мне приходит в голову, что проект все еще может быть построен, но #define где-то можно было изменить.
В любом случае, мне пришло в голову, что я могу быть уверен, что никаких важных изменений не было сделано, проверив двоичные файлы. Мне было интересно, есть ли у кого-нибудь совет, как лучше всего это сделать? Очевидная проблема заключается в том, что небольшой объем метаданных в двоичных файлах изменится из-за метаданных компилятора о времени сборки и т. д.
Идеи на данный момент:
Любые идеи? А кто-нибудь знает инструмент, который понимает заголовки PE, как я описываю?
Да, думаю, это правда. Но это вопрос, на который, скорее всего, знают ответ только коллеги-программисты.
@Andrew Я делаю это в начале графика проекта, поэтому он будет регрессировать. Насколько я понимаю, это технический долг. Кроме того, если можно показать, что двоичные файлы идентичны по функциям, я счастлив на этом этапе проекта.
Некоторые компиляторы, как правило, недетерминированы. Даже один и тот же входной код не гарантирует генерации одного и того же вывода. Проверка семантического равенства двоичных файлов - сложная задача. Вам нужно полагаться на свои тестовые примеры, чтобы быть уверенным, что ничего не сломалось.
скорее всего, ваши двоичные файлы будут отличаться из-за разницы в отладочной информации и возможного удаления неиспользуемого кода. Так что в этом случае никакое сравнение не может быть достоверным. Лучше всего будет тщательно протестировать новый код, как было предложено выше. Для сравнения расширений макросов может быть проще запустить cpp и сравнить связанные части расширенных текстов.
@AjayBrahmakshatriya Правда? Я никогда не слышал этого раньше. Мне даже больше интересно попробовать идею дизассемблера сейчас ...
Компиляторы @Benj используют наборы, карты и многие другие структуры данных. Поведение многих из них не дает гарантий заказа. Я не могу предоставить вам пример того же источника, генерирующего разные двоичные файлы, но я твердо верю, что это происходит.
@AjayBrahmakshatriya Возможно, вы правы, и в этом случае этот подход не сработает. Я собираюсь попробовать разобрать, чтобы вы знали, как это происходит.
@Benj, вы можете прочитать обсуждение это. OP в этом вопросе опубликовал пример, в котором они получают другой результат. Также предоставили сборочный дамп.
Вам не нужно дизассемблировать двоичный файл, вы можете сгенерировать сборку, используя опцию -S в gcc и clang. Я помню, что у cl есть флаг /FA. Однако будьте осторожны с номерами строк и другой отладочной информацией. Вы можете удалить его из вывода, чтобы сохранить только инструкции.
@AjayBrahmakshatriya Это хорошая идея, я должен был подумать об этом.





Заголовок PE всегда находится в одном и том же месте и имеет размер только до 512 байт (точно). так что просто отсеките первые 512 байт и сравните результаты.
Я пропускаю их через xxd для преобразования файлов в шестнадцатеричный формат, затем сравниваю полученные текстовые файлы (подойдет любая программа сравнения текста, но для получения xxd вам понадобится командная строка git).
xxd -p -c 4 < Truncatedfile1.exe > output.diff1
или
tail -n -512 < File1.exe | xxd -p -c 4 > output1.hex
tail -n -512 < File2.exe | xxd -p -c 4 > output2.hex
git diff --no-index --color output1.hex output2.hex
Обратите внимание, что я сделал строки длиной всего 4 байта, чтобы иметь шанс, что выравнивание (особенно происходящее в разделах данных) вернет мне форму строк, когда между ними вставлено нечетное количество байтов. Если вам особенно повезло, ваш код также выровнен по DWORD, и тогда он также будет работать с вашим кодом.
Спасибо! Похоже, этот метод сработал для вас? Некоторые в комментариях говорят, что компиляторы слишком недетерминированы, чтобы эта идея сработала.
Что ж, я редактирую двоичные файлы с помощью автоматизированных материалов в двоичном масштабе, и как тестировщик программного обеспечения у меня есть некоторый опыт в проверке различий. Я просто подумал о том, как можно различать разделы данных, и вспомнил, что они обычно выровнены по двойному слову, поэтому я подумал, что xxd с 4 байтами на строку будет хорошей идеей также для перекомпилированных программ.