Поиск по сайту:

Как сравнить бинарные файлы в Linux


Как проверить, совпадают ли два бинарных файла Linux? Если это исполняемые файлы, любые различия могут означать нежелательное или злонамеренное поведение. Вот самый простой способ проверить, отличаются ли они.

Сравнение бинарных файлов

В Linux есть множество способов сравнения и анализа текстовых файлов. Команда diff сравнит два файла и выделит различия. Он может даже предоставить несколько строк по обе стороны от изменений, чтобы обеспечить некоторый контекст вокруг измененных строк. А команда colordiff добавляет цвет, чтобы сделать визуальный анализ различий еще проще.

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

В мире бинарных файлов все не так просто. Двоичные файлы не состоят из простого текста. Они состоят из множества байтов, содержащих числовые значения. Если это сжатый файл, такой как архив TAR или файл ZIP, эти значения представляют собой сжатые файлы, которые хранятся внутри файла архива, а также таблицы символов, необходимые для распаковки и извлечения файлов.

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

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

Алгоритмы безопасного хеширования

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

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

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

ls -l *.so

Файлы имеют одинаковый размер, одинаковые отметки даты и времени. Стороннему наблюдателю они покажутся одинаковыми. Давайте воспользуемся командой sha256sum и сгенерируем хэш для каждого файла.

sha256sum binary_file1.so
sha256sum binary_file2.so

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

Нахождение различий

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

Если мы используем diff для двух двоичных файлов, мы получим немного неутешительный ответ.

diff binary_file1.so binary_file2.so

Мы уже знали, что файлы были разными. Давайте попробуем cmp .

cmp binary_file1.so binary_file2.so

Это говорит нам немного больше. Первым байтом, который отличается между двумя файлами, является байт номер 13451. То есть, считая от начала двоичного файла, байт 13451 отличается в двух двоичных файлах. Итак, 13451 — это смещение первого отличия от начала файла.

Просто случайно в файле будут байты, содержащие шестнадцатеричное значение 0x10. Это значение, которое Linux использует в текстовых файлах в качестве символа конца строки. Команда cmp обнаружила 131 байт с этим значением между началом двоичного файла и местоположением первой разницы. Поэтому он думает, что находится в строке 132. В данном контексте это действительно ничего не значит.

Если мы добавим параметр -l (подробный), мы начнем получать полезную информацию.

cmp -l binary_file1.so binary_file2.so

Перечислены все отличающиеся байты. Отображается номер байта или смещение, значение из первого файла и значение из второго файла, по одному байту на строку вывода.

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

Инструмент hexdump создаст дамп двоичного файла в окно терминала. Если мы используем параметр -C (канонический), вывод будет перечислять в каждой строке смещение, значения 16 байтов по этому смещению и, если есть, ASCII-представление значений байтов. .

hexdump -C binary_file1.so

Мы можем использовать выходные данные hexdump в качестве входных данных для diff, позволяя diff работать так, как если бы он читал два текстовых файла.

diff <(hexdump binary_file1.so) <(hexdump binary_file2.so)

diff находит отличающиеся строки и показывает шестнадцатеричные значения байтов из первого файла над значениями из второго файла. Смещение первой строки равно 0x3480 или 13440 в десятичном формате. Ранее cmp сообщил нам, что первое изменение произошло в байте 13451, то есть 0x348B. Это действительно соответствует тому, что мы видим здесь.

Вывод из diff состоит из двухбайтовых блоков. Первая пара байтов — это байты 0 и 1 по смещению 0x3480, второй блок содержит байты 2 и 3 по смещению. Блок 6 будет содержать байты 0xA и 0xB или 10 и 11 в десятичном виде. Это байты 13450 и 13451. И мы видим, что это первые отличающиеся байты. Первые пять пар байтов одинаковы в обоих файлах.

Однако, поскольку diff считает от нуля, то, что cmp вызывает 13451, будет байтом 13540 для diff. И чтобы сделать ситуацию еще более запутанной, порядок байтов в каждом двухбайтовом блоке меняется на противоположный с помощью diff. На самом деле байты перечислены в следующем порядке: 1 и 0, 3 и 2, 5 и 4, 7 и 6 и так далее.

Команда также требует больших вычислительных ресурсов — два шестнадцатеричных дампа и diff одновременно — особенно если сравниваемые файлы большие.

Но если hexdump -C может отправить ASCII-версию двоичного файла в окно терминала, почему бы нам не перенаправить вывод в текстовые файлы, а затем сравнить эти два текстовых файла с diff ?

hexdump -C binary_file1.so > binary1.txt
hexdump -C binary_file2.so > binary2.txt
diff binary1.txt binary2.txt

Разница между двумя файлами отображается в двух коротких отрывках. Рядом с ними есть ASCII-представление. Для каждого различия между файлами будет пара извлечений. В этом примере есть только одно отличие.

Все это очень хорошо, но разве не было бы здорово, если бы было что-то, что делало бы все это за вас?

VBinDiff

Программу VBinDiff можно установить из обычных репозиториев для всех основных дистрибутивов. Чтобы установить его в Ubuntu, используйте эту команду:

sudo apt install vbindiff

В Fedora вам нужно ввести:

sudo dnf install vbindiff

Пользователям Manjaro необходимо использовать pacman.

sudo pacman -Sy vbindiff

Чтобы использовать программу, передайте имена двух двоичных файлов в командной строке.

vbindiff binary_file1.so binary_file2.so

Откроется терминальное приложение, показывающее оба файла в режиме прокрутки.

Для перемещения по файлам можно использовать колесо прокрутки мыши или клавиши «Стрелка вверх», «Стрелка вниз», «Домой», «Конец», «PageUp» и «PageDown». Оба файла будут прокручиваться.

Нажмите клавишу «Ввод», чтобы перейти к первому различию. Разница выделена в обоих файлах.

Если бы различий было больше, нажатие «Enter» отобразило бы следующее различие. Нажатие «q» или «Esc» приведет к выходу из программы.

Какая разница?

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

Но если вам разрешено устанавливать пакеты, VBinDiff упростит и ускорит ваш рабочий процесс. И на самом деле, использование VBinDiff с одним бинарным файлом — это простой и удобный способ просматривать бинарные файлы, что является приятным бонусом.