
У меня есть три бинарных файла (дампа памяти). Назовем их file1
, file2
, file3
. Я пытаюсь отладить какое-то программное обеспечение и переключаю переключатель.
file1
= выключитьfile2
= включитьfile3
= выключить
Мне нужно знать, какие байты изменились между file1
и file2
, которые затем также изменились обратно на те же значения (как file1
) в file3
.
Между ними происходит много не связанных между собой изменений file1
, file2
поэтому diff
одного этого недостаточно, чтобы определить, что именно меняется при переключении этого переключателя. Я пытаюсь определить уникальные байты энтропии, которые изменяются с file1
, 2
, 3
,…
Я знаю, что есть такие инструменты, как xxd
, diff
, vimdiff
, colordiff
. Я просто не уверен, как лучше всего их использовать для решения этой проблемы.
решение1
Чтобы узнать байты, которые изменились между file1
и , file2
а также их соответствующие значения, используйте cmp -l
:
cmp -l file1 file2 > changes12
Аналогично для file3
и file2
. Хитрость в том, чтобы всегда исследовать в одном и том же направлении (здесь: переключиться с выключения на включение), поэтому я и ставлю file2
в конце:
cmp -l file3 file2 > changes32
Теперь вы можете найти идентичные изменения:
comm -12 changes12 changes32
и вывод будет таким (пример):
1629 152 112
что означает, что байт 1629
(десятичный, нумерация начинается с 1
) изменился с 152
(восьмеричного) на 112
(восьмеричного).
Примечания:
cmp -l
в моем Ubuntu "разбивает на столбцы" свой вывод. Это означает, что он может печатать строки с ведущими пробелами, ширина первого столбца зависит от размера ввода. Я думаю, что некоторые реализации могут этого не делать. Есть несколько проблем:- Если исходные файлы имеют разный размер (вероятно, не ваш случай), один из них
cmp
может генерировать более широкий первый столбец, чем другой. В контексте latercomm
это неприемлемо. Вы можете "деколонизировать" вывод, передав его вawk '{print $1" "$2" "$3}'
. - Если вывод не "колоночный" (или был "деколоночный"),
comm
может возникнуть жалоба на то, что файлы не отсортированы. Вам нужноsort
(неsort -n
) перед сохранением вchangesAB
. Это может привести к несколько неожиданному порядку (например,23
будет отображаться другой байтпослеотличающийся байт100453
), который можно исправить, перенаправив выводcomm
вsort -n
.
- Если исходные файлы имеют разный размер (вероятно, не ваш случай), один из них
changes*
Файлы могут быть огромными. Они промежуточные и временные, поэтому замена процесса может быть хорошим подходом. Но это не POSIX:# Korn shell syntax example comm -12 <(cmp -l file1 file2) <(cmp -l file3 file2)
Вывод из
comm
можно использовать с еще одним выводом и еще одним выводом дляcmp
лучшей фильтрации несвязанных изменений:comm -12 changes12 changes32 > result1 cmp -l file4 file5 | comm -12 - result1 > result2 cmp -l file6 file5 | comm -12 - result2 > result3
Но помни:
- Вам всегда нужно двигаться
cmp
в одном и том же направлении (например, от выключения к включению). - Остерегайтесь этого:Использование одного и того же файла в качестве stdin и stdout приводит к пустому файлу.
… | comm -12 - result1 > result1
неправильно.
- Вам всегда нужно двигаться
Документация:
решение2
Я пользователь Windows и уже много лет использую Beyond Compare для сравнения файлов, в том числе для сравнения трех файлов (по два за раз) друг с другом.
Похоже, у Beyond Compare также есть дистрибутив Linux, так что вам, возможно, будет интересно его протестировать.
https://www.scootersoftware.com/download.php?zz=kb_linux_install
Я знаю, что в версии Windows есть опции, чтобы показать только различия, а также множество других функций, которые могут вам помочь. Я не помню, есть ли у них 3-стороннее сравнение или нет.
Я не разработчик и не продавец, мне просто очень нравится это программное обеспечение.
решение3
Основываясь на ответе Камиля, я использовал это, чтобы получить то, что мне было нужно:
cmp -l файл1 файл2 | awk '{print $1" "$2" "$3}' | сортировка > изменения_12
cmp -l file3 file2 | awk '{print $1" "$2" "$3}' | сортировка > изменения_32
comm -12 изменения_12 изменения_32 > общие_изменения