Как сравнить бинарные файлы в Linux
Опубликовано: 2022-08-20Как проверить, совпадают ли два бинарных файла Linux? Если это исполняемые файлы, любые различия могут означать нежелательное или злонамеренное поведение. Вот самый простой способ проверить, отличаются ли они.
Сравнение бинарных файлов
В Linux есть множество способов сравнения и анализа текстовых файлов. Команда diff
сравнит два файла и выделит различия. Он может даже предоставить несколько строк по обе стороны от изменений, чтобы обеспечить некоторый контекст вокруг измененных строк. А команда colordiff
добавляет цвет, чтобы сделать визуальный анализ различий еще проще.
Разработчики и авторы используют diff
, чтобы выделить различия между различными версиями файлов исходного кода программы или черновиков текстов. Это быстро и просто, и вам не нужны никакие технические навыки, чтобы увидеть различия между строками текста.
В мире бинарных файлов все не так просто. Двоичные файлы не состоят из простого текста. Они состоят из множества байтов, содержащих числовые значения. Если это сжатый файл, такой как архив TAR или файл ZIP, эти значения представляют собой сжатые файлы, которые хранятся внутри файла архива, а также таблицы символов, необходимые для распаковки и извлечения файлов.
Если двоичный файл является исполняемым файлом, числовые значения байтов файла интерпретируются как такие вещи, как инструкции машинного кода для ЦП, метаданные, метки или закодированные данные. Изменения в двоичном файле или файле библиотеки могут привести к различиям в поведении, когда двоичный файл выполняется или используется другим приложением.
Легко подделать дату и время создания или изменения файла. Это означает, что может быть две версии файла с одинаковым именем, размером файла (если изменения заменяют существующее содержимое байт за байтом) и отметками даты. И все же, один из файлов мог быть изменен.
Алгоритмы безопасного хеширования
Алгоритм безопасного хеширования — это математический алгоритм. Он создает 64-битное значение, сканируя все байты в файле и применяя к ним математическое преобразование для создания хеш-значения. В любой день один и тот же файл всегда будет производить один и тот же хэш. Даже разница в один байт приведет к совершенно другому хешу.
Вы часто будете видеть хэш файла, отображаемый на его странице загрузки. Вы должны сгенерировать хэш для файла после его загрузки. Если он отличается от хеша, отображаемого на веб-странице, вы знаете, что файл скомпрометирован. Он либо был подделан и заменен подлинным файлом, чтобы заставить людей загружать испорченный файл, либо он был поврежден при передаче.
На нашем тестовом компьютере у нас есть две копии одного и того же файла, общей библиотеки. Файлы были переименованы, чтобы они могли находиться в одном каталоге. Теоретически эти файлы должны быть одинаковыми. В конце концов, они должны быть одной и той же версией общей библиотеки.
лс -л *.со
Файлы имеют одинаковый размер, одинаковые метки даты и метки времени. Стороннему наблюдателю они покажутся одинаковыми. Давайте воспользуемся командой sha256sum
и сгенерируем хэш для каждого файла.
sha256sum двоичный_файл1.so
sha256sum двоичный_файл2.so
Хэши совершенно разные, что явно указывает на наличие различий между двумя файлами. Если веб-сайт показывает хэш подлинного файла, вы можете отбросить несоответствующий файл.
Нахождение различий
Если вы хотите посмотреть на изменения, есть способы сделать это тоже. Вам не нужно уметь декомпилировать файл или разбираться в ассемблере или машинном коде, чтобы увидеть изменения. Понимание того, что означают эти изменения и какова их цель, конечно же, потребует более глубоких технических знаний. Но простое знание того, насколько существенны изменения, может указывать на то, что произошло с файлом.
Если мы используем diff
для двух двоичных файлов, мы получим немного неутешительный ответ.
diff двоичный_файл1.so двоичный_файл2.so
Мы уже знали, что файлы были разными. Попробуем cmp
.
cmp двоичный_файл1.so двоичный_файл2.so
Это говорит нам немного больше. Первым байтом, отличающимся между двумя файлами, является байт номер 13451. То есть, считая от начала двоичного файла, байт 13451 различается в двух двоичных файлах. Итак, 13451 — это смещение первого отличия от начала файла.
Просто случайно в файле будут байты, содержащие шестнадцатеричное значение 0x10. Это значение, которое Linux использует в текстовых файлах в качестве символа конца строки. Команда cmp
обнаружила 131 байт с этим значением между началом двоичного файла и местоположением первой разницы. Итак, он думает, что находится в строке 132. На самом деле это ничего не значит в данном контексте.
Если мы добавим параметр -l
(подробный), мы начнем получать полезную информацию.
cmp -l двоичный_файл1.so двоичный_файл2.so
Перечислены все отличающиеся байты. Отображается номер байта или смещение, значение из первого файла и значение из второго файла, по одному байту на строку вывода.
Значения байтов отображаются в восьмеричном формате вместо обычного шестнадцатеричного формата, используемого для двоичных файлов. Тем не менее, мы узнали кое-что еще. Все измененные байты находятся в одной непрерывной последовательности. Их смещения увеличиваются на единицу для каждого байта.
Инструмент hexdump
выгрузит двоичный файл в окно терминала. Если мы используем параметр -C
(канонический), вывод будет перечислять в каждой строке смещение, значения 16 байтов по этому смещению и, если оно есть, ASCII-представление значений байтов.
шестнадцатеричный дамп -C двоичный_файл1.so
Мы можем использовать выходные данные hexdump
в качестве входных данных для diff
, позволяя diff
работать так, как если бы он читал два текстовых файла.
diff <(шестнадцатеричный дамп двоичного_файла1.so) <(шестнадцатеричный дамп двоичного_файла2.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 и так далее.
Эта команда также требует значительных вычислительных ресурсов — два hexdumps
и diff
сразу — особенно если сравниваемые файлы большие.
Но если hexdump -C
может отправить ASCII-версию двоичного файла в окно терминала, почему бы нам не перенаправить вывод в текстовые файлы, а затем сравнить эти два текстовых файла с помощью diff
?
шестнадцатеричный дамп -C двоичный_файл1.so> двоичный_файл1.txt
шестнадцатеричный дамп -C двоичный_файл2.so> двоичный_файл2.txt
разница двоичный1.txt двоичный2.txt
Разница между двумя файлами отображается в двух коротких отрывках. Рядом с ними есть ASCII-представление. Для каждого различия между файлами будет пара извлечений. В этом примере есть только одно отличие.
Все это очень хорошо, но было бы здорово, если бы было что-то, что делало бы все это за вас?
VBinDiff
Программу VBinDiff можно установить из обычных репозиториев для всех основных дистрибутивов. Чтобы установить его в Ubuntu, используйте эту команду:
sudo apt установить vbindiff
В Fedora вам нужно ввести:
sudo dnf установить vbindiff
Пользователям Manjaro необходимо использовать pacman
.
sudo pacman -Sy vbindiff
Чтобы использовать программу, передайте имена двух двоичных файлов в командной строке.
vbindiff двоичный_файл1.со двоичный_файл2.со
Откроется терминальное приложение, показывающее оба файла в режиме прокрутки.
Для перемещения по файлам можно использовать колесо прокрутки мыши или клавиши «Стрелка вверх», «Стрелка вниз», «Домой», «Конец», «PageUp» и «PageDown». Оба файла будут прокручиваться.
Нажмите клавишу «Ввод», чтобы перейти к первому различию. Разница выделена в обоих файлах.
Если бы различий было больше, нажатие «Enter» отобразило бы следующее различие. Нажатие «q» или «Esc» приведет к выходу из программы.
Какая разница?
Если вы работаете на чужом компьютере и вам не разрешено устанавливать какие-либо пакеты, вы можете использовать cmp
, diff
и hexdump
. Если вам нужно зафиксировать выходные данные для дальнейшей обработки, вы также можете использовать эти инструменты.
Но если вам разрешено устанавливать пакеты, VBinDiff упростит и ускорит ваш рабочий процесс. И на самом деле, использование VBinDiff с одним бинарным файлом — это простой и удобный способ просматривать бинарные файлы, что является приятным бонусом.
СВЯЗАННЫЕ С: Как заглянуть внутрь двоичных файлов из командной строки Linux