Как сравнить двоичные файлы в Linux?

Мне нужно сравнить два двоичных файла и получить вывод в форме

& л; FileOffset-гекс > & Lt; файл1 байт-гекс > & Lt; файл2 байт-гекс >

для каждого другого байта. Так что если file1.bin есть

00 90 00 11

в двоичной форме и file2.bin есть

00 91 00 10

Я хочу получить что-то вроде

00000001 90 91
  00000003 11 10

Каков самый простой способ достижения цели? Стандартный инструмент? Какой-то сторонний инструмент?

(Примечание: cmp -l должен быть убит огнем, он использует десятичную систему для смещений и восьмеричную для байтов.)

251 голос | спросил frustratedCmpNoLongerUser 29 MarpmMon, 29 Mar 2010 19:28:57 +04002010-03-29T19:28:57+04:0007 2010, 19:28:57

12 ответов


142

Это будет печатать смещение и байты в шестнадцатеричном формате:

cmp -l file1.bin file2.bin | gawk '{printf "% 08X% 02X% 02X \ n", $ 1, strtonum (0 $ 2), strtonum (0 $ 3)}'

Или выполните $ 1-1, чтобы первый начальный сдвиг смещения начинался с 0.

cmp -l file1.bin file2.bin | gawk '{printf "% 08X% 02X% 02X \ n", $ 1-1, strtonum (0 $ 2), strtonum (0 $ 3)}'

К сожалению, strtonum () специфичен для GAWK, поэтому для других версий awk, например, mawk, вам нужно будет использовать функцию преобразования от восьмеричного к десятичному. Например,

cmp -l file1.bin file2.bin | mawk 'oct2dec (oct, dec) {для (i = 1; i <= длина (oct); i ++) {dec * = 8; dec + = substr (oct, i, 1)}; return dec} {printf "% 08X% 02X% 02X \ n", $ 1, oct2dec ($ 2), oct2dec ($ 3)} '

Сломанный для удобочитаемости:

cmp -l file1.bin file2.bin |
    mawk 'oct2dec (oct, dec) {
              для (i = 1; i <= длина (oct); i ++) {
                  dec * = 8;
                  dec + = substr (oct, i, 1)
              };
              return dec
          }
          {
              printf "% 08X% 02X% 02X \ n", $ 1, oct2dec ($ 2), oct2dec ($ 3)
          }»
ответил Dennis Williamson 29 MarpmMon, 29 Mar 2010 20:30:19 +04002010-03-29T20:30:19+04:0008 2010, 20:30:19
137

Как ~ quack указал:

% xxd b1> b1.hex
 % xxd b2> b2.hex

И затем

% diff b1.hex b2.hex

или

% vimdiff b1.hex b2.hex
ответил akira 29 MarpmMon, 29 Mar 2010 20:07:55 +04002010-03-29T20:07:55+04:0008 2010, 20:07:55
56

Попробуйте diff в следующей комбинации замещения процесса zsh /bash и colordiff в CLI:

diff -y <(xxd foo1.bin) <(xxd foo2.bin) | colordiff

Где:

  • -y показывает разницу бок о бок (необязательно)
  • xxd - это инструмент CLI для создания вывода hexdump двоичного файла
  • colordiff будет раскрасить вывод diff (установить через: sudo apt-get install colordiff)
  • добавить -W200 в diff для более широкого вывода

Советов:

  • Если файлы имеют большой размер, добавьте ограничение (например, -l1000) для каждого xxd

Пример вывода:

ответил kenorb 6 thEurope/Moscowp30Europe/Moscow09bEurope/MoscowSun, 06 Sep 2015 00:14:55 +0300 2015, 00:14:55
48

Есть инструмент под названием DHEX , который может выполнять эту работу, и есть еще один инструмент под названием VBinDiff .

Для строго командной строки попробуйте JDIFF .

ответил njd 29 MarpmMon, 29 Mar 2010 19:41:30 +04002010-03-29T19:41:30+04:0007 2010, 19:41:30
25

Метод, который работает для добавления /удаления байта

diff <(od -An -tx1 -w1 -v file1) \
     <(od -An -tx1 -w1 -v file2)

Создайте тестовый пример с единственным удалением байта 64:

для i в `seq 128`; do printf "% 02x" "$ i"; сделано | xxd-r-p> file1
для i в `seq 128`; do, если ["$ i" -ne 64]; затем printf "% 02x" $ i; Fi; сделано | xxd-r-p> file2

Вывод:

64d63
& Lt; 40

Если вы также хотите увидеть версию ASCII символа:

bdiff () (
  f () (
    od -An -tx1c -w1 -v "$ 1" | paste -d '' - -
  )
  diff <(f "$ 1") <(f "$ 2")
)

bdiff file1 file2

Вывод:

64d63
& Lt; 40 @

Протестировано на Ubuntu 16.04.

Я предпочитаю od поверх xxd, потому что:

  • it это POSIX , xxd нет (поставляется с Vim)
  • имеет -An, чтобы удалить столбец адресов без awk.

Объяснение команды:

  • -An удаляет столбец адресов. Это важно, иначе все строки будут отличаться после добавления /удаления байта.
  • -w1 помещает один байт в строку, так что diff может его использовать. Крайне важно иметь по одному байту в строке, иначе каждая строка после удаления перестает быть фазой и отличается. К сожалению, это не POSIX, но присутствует в GNU.
  • -tx1 - это представление, которое вы хотите, измените на любое возможное значение, если вы сохраняете 1 байт на строку.
  • -v предотвращает аббревиатуру повторения asterisk *, которая может мешать diff
  • paste -d '' - - объединяет каждые две строки. Нам это нужно, потому что hex и ASCII переходят в отдельные смежные строки. Взято из: https://stackoverflow.com/questions/8987257/concatenating-every -другие линии-с-следующего
  • мы используем скобку () для определения bdiff вместо {}, чтобы ограничить область внутренней функции f, см. также: https: //stackoverflow. ком /вопросы /8426077 /как определимая-а-функцию-внутри-другая-функция-в-Баша

См. также:

ответил Ciro Santilli 新疆改造中心 六四事件 法轮功 4 PMpSat, 04 Apr 2015 23:31:59 +030031Saturday 2015, 23:31:59
12

Короткий ответ

vimdiff <(xxd -c1 -p first.bin) <(xxd -c1 -p second.bin)

При использовании hexdumps и text diff для сравнения двоичных файлов, особенно xxd, добавление и удаление байтов становятся смещениями в адресе, что может затруднить их просмотр. Этот метод сообщает xxd не выводить адреса и выводить только один байт на строку, что, в свою очередь, показывает, какие именно байты были изменены, добавлены или удалены. Вы можете найти адреса позже, ища интересные последовательности байтов в более «нормальном» hexdump (вывод xxd first.bin).

ответил Evgeny 22 PMpWed, 22 Apr 2015 15:10:51 +030010Wednesday 2015, 15:10:51
10

Я бы рекомендовал hexdump для сбрасывания двоичных файлов в текстовый формат и kdiff3 для просмотра diff.

hexdump myfile1.bin> myfile1.hex
hexdump myfile2.bin> myfile2.hex
kdiff3 myfile1.hex myfile2.hex
ответил BugoK 12 J0000006Europe/Moscow 2013, 11:46:34
4

hexdiff - это программа, предназначенная для выполнения именно того, что вы ищете.

Использование:

hexdiff file1 file2

Он отображает шестнадцатеричный (и 7-разрядный ASCII) двух файлов один над другим, с любыми различиями. Посмотрите на man hexdiff для команд, перемещающихся в файле, и простое q закроется.

ответил Mick 7 +03002015-10-07T07:11:31+03:00312015bEurope/MoscowWed, 07 Oct 2015 07:11:31 +0300 2015, 07:11:31
3

Он не может строго ответить на вопрос, но я использую это для разных двоичных файлов:

gvim -d <(xxd -c 1 ~ /file1.bin | awk '{print $ 2, $ 3}') <(xxd -c 1 ~ /file2.bin | awk '{print $ 2 , $ 3} ')

Он печатает оба файла как шестнадцатеричные и значения ASCII , по одному байту в строке и затем использует средство сравнения Vim, чтобы визуально визуализировать их.

ответил John Lawrence Aspden 7 thEurope/Moscowp30Europe/Moscow09bEurope/MoscowWed, 07 Sep 2011 19:47:54 +0400 2011, 19:47:54
0

https://security.googleblog.com /2016/03/bindiff-now-available-for-free.html

BinDiff - отличный инструмент для сравнения двоичных файлов, которые недавно были открыты.

ответил Evgeny 23 MarpmWed, 23 Mar 2016 23:18:41 +03002016-03-23T23:18:41+03:0011 2016, 23:18:41
0

dhex http://www.dettus.net/dhex/

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

ответил Vincent Vega 18 PM00000020000002831 2017, 14:25:28
-2

Я рекомендую IDA Pro анализировать двоичные файлы. Затем сравнение можно выполнить с помощью плагина для IDA, такого как BinDiff .

ответил user3119546 30 MonEurope/Moscow2013-12-30T19:04:31+04:00Europe/Moscow12bEurope/MoscowMon, 30 Dec 2013 19:04:31 +0400 2013, 19:04:31

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132