277

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

<fileoffset-hex> <file1-byte-hex> <file2-byte-hex>

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

  00 90 00 11

в двоичном виде и file2.bin

  00 91 00 10

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

  00000001 90 91
  00000003 11 10

Есть ли способ сделать это в Linux? Я знаю о cmp -l но он использует десятичную систему для смещений и восьмеричную для байтов, которых я хотел бы избежать.

14 ответов14

164

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

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 'function oct2dec(oct,     dec) {for (i = 1; i <= length(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 'function oct2dec(oct,    dec) {
              for (i = 1; i <= length(oct); i++) {
                  dec *= 8;
                  dec += substr(oct, i, 1)
              };
              return dec
          }
          {
              printf "%08X %02X %02X\n", $1, oct2dec($2), oct2dec($3)
          }'
152

Как сказал Кряк :

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

А потом

 % diff b1.hex b2.hex

или же

 % vimdiff b1.hex b2.hex
72

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

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

Куда:

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

подсказки:

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

Образец вывода:

вывод двоичного файла в терминале - diff -y <(xxd foo1.bin) <(xxd foo2.bin) | colordiff

50

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

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

26

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

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

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

for i in `seq 128`; do printf "%02x" "$i"; done | xxd -r -p > file1
for i in `seq 128`; do if [ "$i" -ne 64 ]; then printf "%02x" $i; fi; done | xxd -r -p > file2

Выход:

64d63
<  40

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

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

bdiff file1 file2

Выход:

64d63
<   40   @

Проверено на Ubuntu 16.04.

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

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

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

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

Смотрите также:

13

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

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

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

11

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

hexdump myfile1.bin > myfile1.hex
hexdump myfile2.bin > myfile2.hex
kdiff3 myfile1.hex myfile2.hex
4

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

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

hexdiff file1 file2

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

3

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

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

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

0

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

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

0

Вы можете использовать инструмент gvimdiff , который входит в пакет vim-gui-common

sudo apt-get update

sudo apt-get установить vim-gui-common

Затем вы можете сравнить 2 шестнадцатеричных файла, используя следующие команды:

ubuntu> gvimdiff <hex-file1> <hex-file2>

Это все. Надеюсь, что помощь!

-1

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

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

-2

Продуктом с открытым исходным кодом для Linux (и всего остального) является Radare, который явно использует radiff2 для этой цели. Я проголосовал за это, потому что у меня и у других один и тот же вопрос в вопросе, который вы задаете

за каждый другой байт

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

Чуть более практичным является radiff -O . Параметр -O предназначен для "" Выполнять проверку кода со всеми байтами, а не только с фиксированными байтами кода операции ""

0x000000a4 0c01 => 3802 0x000000a4
0x000000a8 1401 => 3802 0x000000a8
0x000000ac 06 => 05 0x000000ac
0x000000b4 02 => 01 0x000000b4
0x000000b8 4c05 => 0020 0x000000b8
0x000000bc 4c95 => 00a0 0x000000bc
0x000000c0 4c95 => 00a0 0x000000c0

Как и IDA Pro, Radare - это основной инструмент для бинарного анализа, вы также можете показывать разностное дифференцирование с помощью -d или отображать дизассемблированные байты вместо шестнадцатеричных с помощью -D .

Если вы задаете такие вопросы, проверьте

-3

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

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .