2010-03-29 15:28:57 +0000 2010-03-29 15:28:57 +0000
324
324

Como posso comparar ficheiros binários em Linux?

Preciso de comparar dois ficheiros binários e obter a saída na forma:

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

para cada byte diferente. Então se file1.bin é

00 90 00 11

em formato binário e file2.bin é

00 91 00 10

Quero obter algo como

00000001 90 91
  00000003 11 10

Existe uma maneira de fazer isto no Linux? Eu sei sobre o cmp -l mas ele usa um sistema decimal para offsets e octal para bytes que eu gostaria de evitar.

Respostas (14)

182
182
182
2010-03-29 16:30:19 +0000

Isto irá imprimir o offset e os bytes em hex:

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

ou fazer $1-1 para que o primeiro offset impresso comece em 0.

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

Infelizmente, strtonum() é específico para GAWK, por isso para outras versões de awk-e.g., mawk-you precisará de usar uma função de conversão octal-para-decimal. Por exemplo,

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)}'

Broken out para legibilidade:

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)
          }'
174
174
174
2010-03-29 16:07:55 +0000

Como ~quack salientou:

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

ou

% vimdiff b1.hex b2.hex
112
112
112
2015-09-05 21:14:55 +0000

diff + xxd

Tente diff na seguinte combinação de substituição do processo zsh/bash:

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

Onde:

  • -y mostra-lhe diferenças lado a lado (opcional).
  • xxd é uma ferramenta CLI para criar uma saída hexdump do ficheiro binário.
  • Adicione -W200 a diff para uma saída mais ampla (de 200 caracteres por linha).
  • Para cores, use colordiff como mostrado abaixo.

colordiff + xxd

Se tem colordiff, pode colorir a saída de diff, por exemplo:

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

Caso contrário instale via: sudo apt-get install colordiff.

Saída de amostra:

vimdiff + xxd

Também pode usar vimdiff, e.g.

vimdiff <(xxd foo1.bin) <(xxd foo2.bin)

Dicas:

  • se os ficheiros forem demasiado grandes, adicione limite (e.g. -l1000) para cada xxd
60
60
60
2010-03-29 15:41:30 +0000

Há uma ferramenta chamada DHEX que pode fazer o trabalho, e há outra ferramenta chamada VBinDiff .

Para uma abordagem estritamente de linha de comando, tente jojodiff .

28
28
28
2015-04-04 20:31:59 +0000

Método que funciona para adição / eliminação de bytes

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

Gerar um caso de teste com uma única remoção de byte 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

Saída:

64d63
< 40

Se também quiser ver a versão ASCII do personagem:

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

bdiff file1 file2

Saída:

64d63
< 40 @

Saída: Testado no Ubuntu 16. 04.

Prefiro od em vez de xxd porque:

Explicação do comando:

14
14
14
2015-04-22 12:10:51 +0000

Resposta curta

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

Quando se utilizam hexdumps e diff de texto para comparar ficheiros binários, especialmente xxd, as adições e remoções de bytes tornam-se mudanças de endereço que podem dificultar a sua visualização. Este método diz xxd para não emitir endereços, e para emitir apenas um byte por linha, que por sua vez mostra exactamente quais os bytes que foram alterados, adicionados ou removidos. Pode encontrar os endereços mais tarde, procurando as sequências interessantes de bytes num hexdump mais “normal” (output of xxd first.bin).

11
11
11
2013-06-12 07:46:34 +0000

Eu recomendaria hexdump para despejar arquivos binários em formato texto e kdiff3 para visualização dif.

hexdump myfile1.bin > myfile1.hex
hexdump myfile2.bin > myfile2.hex
kdiff3 myfile1.hex myfile2.hex
6
6
6
2015-10-07 04:11:31 +0000

O hexdiff é um programa concebido para fazer exactamente o que procura.

Utilização:

hexdiff file1 file2

Apresenta o hex (e ASCII de 7 bits) dos dois ficheiros um acima do outro, com as eventuais diferenças assinaladas. Olhe para o man hexdiff para os comandos para se mover no ficheiro, e um simples q irá desistir.

4
4
4
2011-09-07 15:47:54 +0000

Pode não responder estritamente à pergunta, mas utilizo-a para difundir binários:

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

Imprime ambos os ficheiros como valores hexadecimais e ASCII , um byte por linha, e depois utiliza a facilidade de difusão da Vim para os tornar visuais.

1
1
1
2019-07-25 12:42:04 +0000

A ferramenta de análise de firmware binwalk também tem isto como característica através da sua opção de linha de comando -W/--hexdump que oferece opções como mostrar apenas os diferentes bytes:

-W, --hexdump Perform a hexdump / diff of a file or files
    -G, --green Only show lines containing bytes that are the same among all files
    -i, --red Only show lines containing bytes that are different among all files
    -U, --blue Only show lines containing bytes that are different among some files
    -w, --terse Diff all files, but only display a hex dump of the first file

No exemplo do OP ao fazer binwalk -W file1.bin file2.bin:

1
1
1
2018-10-08 13:52:19 +0000

Pode utilizar gvimdiff ferramenta que está incluída em vim-gui-common pacote

sudo apt-get update

sudo apt-get install vim-gui-common

Depois pode comparar 2 ficheiros hexadecimais utilizando os seguintes comandos :

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

Tha’s all. Espero que isso ajude!

0
0
0
2017-08-18 11:25:28 +0000

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

DHEX é mais do que um simples editor hexadecimal: inclui um modo dif, que pode ser usado para comparar fácil e convenientemente dois arquivos binários. Uma vez que é baseado em ncurses e é temático, ele pode rodar em qualquer número de sistemas e cenários. Com a sua utilização de logs de pesquisa, é possível acompanhar facilmente as alterações em diferentes iterações de ficheiros.

-1
-1
-1
2018-11-09 04:18:32 +0000

O go to open source product on Linux (e tudo mais) é Radare que fornece radiff2 explicitamente para este fim. Eu votei para fechar isto porque eu próprio e outros tenho a mesma pergunta, na pergunta que faz

_ para cada byte diferente_

Mas isso é uma loucura. Porque, como foi perguntado, se inserir um byte no primeiro byte do ficheiro, verificaria que cada byte subsequente era diferente e assim a diff repetiria o ficheiro inteiro, para uma diferença real de um byte.

Um pouco mais prático é radiff -O. O -O é para “Do code diffing with all bytes instead than just the fixed opcode bytes”

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

Como o IDA Pro, Radare é uma ferramenta primária para análise binária, você também pode mostrar delta diffing com -d, ou mostrar os bytes desmontados em vez de hexadecimal com -D.

Se você estiver fazendo este tipo de pergunta, veja

-1
-1
-1
2016-03-23 20:18:41 +0000

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

BinDiff é uma óptima ferramenta de IU para comparar ficheiros binários que foram abertos recentemente.