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

¿Cómo comparo los archivos binarios en Linux?

Necesito comparar dos archivos binarios y obtener la salida en la forma:

<archivo1-byte-hex> \N <archivo2-byte-hex\N

para cada byte diferente. Así que si file1.bin es

00 90 00 11

en forma binaria y file2.bin es

00 91 00 10

Quiero obtener algo como

00000001 90 91
  00000003 11 10

¿Hay alguna manera de hacer esto en Linux? Sé lo de cmp -l pero usa un sistema decimal para las compensaciones y octal para los bytes que me gustaría evitar.

Respuestas (14)

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

Esto imprimirá el offset y los bytes en hexadecimal:

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

O hacer $1-1 para que el primer offset impreso empiece en 0.

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

Desafortunadamente, strtonum() es específico de GAWK, así que para otras versiones de awk-e.g., mawk-necesitará usar una función de conversión octal a decimal. Por ejemplo,

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

Desglosado para la legibilidad:

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 señaló:

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

Y luego

% diff b1.hex b2.hex

o

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

diff + xxd

Prueba diff en la siguiente combinación de sustitución de procesos zsh/bash:

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

Donde:

  • -y te muestra las diferencias una al lado de la otra (opcional).
  • xxd es la herramienta CLI para crear una salida hexdump del archivo binario.
  • Añade -W200 a diff para obtener una salida más amplia (de 200 caracteres por línea).
  • Para los colores, usa colordiff como se muestra a continuación.

colordiff + xxd

Si tiene colordiff, puede colorear la salida de diff, por ejemplo:

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

De lo contrario, instálelo a través de: sudo apt-get install colordiff.

Ejemplo de salida:

vimdiff + xxd

También puede usar vimdiff, por ejemplo

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

Consejos:

  • si los archivos son demasiado grandes, añada un límite (por ejemplo, -l1000) para cada xxd
60
60
60
2010-03-29 15:41:30 +0000

Hay una herramienta llamada DHEX que puede hacer el trabajo, y hay otra herramienta llamada VBinDiff .

Para un acercamiento estrictamente de línea de comando, intenta jojodiff .

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

Método que funciona para la adición/eliminación de bytes

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

Generar un caso de prueba con una sola eliminación del 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

Salida:

64d63
< 40

Si también quieres ver la versión ASCII del personaje:

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

bdiff file1 file2

Salida:

64d63
< 40 @

Probado en Ubuntu 16. 04.

Prefiero od a xxd porque:

  • es es POSIX , xxd no es (viene con Vim)
  • tiene el -An para eliminar la columna de dirección sin awk.

Explicación del comando:

  • -An elimina la columna de dirección. Esto es importante, de lo contrario todas las líneas diferirían después de una adición / eliminación de bytes.
  • -w1 pone un byte por línea, de modo que diff puede consumirlo. Es crucial tener un byte por línea, o de lo contrario todas las líneas después de una eliminación se desfasarían y diferirían. Desafortunadamente, esto no es POSIX, pero está presente en GNU.
  • -tx1 es la representación que quieres, cambia a cualquier valor posible, siempre y cuando mantengas 1 byte por línea.
  • -v evita la abreviatura de repetición de asterisco * que podría interferir con el diff
  • paste -d '' - - se une cada dos líneas. Lo necesitamos porque el hexágono y el ASCII van en líneas adyacentes separadas. Tomado de: https://stackoverflow.com/questions/8987257/concatenating-every-other-line-with-the-next
  • usamos el paréntesis () para definir bdiff en lugar de {} para limitar el alcance de la función interna f, ver también: https://stackoverflow.com/questions/8426077/how-to-define-a-function-inside-another-function-in-bash

Ver también:

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

Respuesta corta

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

Cuando se usan hexdumps y text diff para comparar archivos binarios, especialmente xxd, las adiciones y eliminaciones de bytes se convierten en desplazamientos en el direccionamiento que podrían dificultar la visualización. Este método le dice a xxd que no emita direcciones, y que emita sólo un byte por línea, lo que a su vez muestra exactamente qué bytes fueron cambiados, añadidos o eliminados. Puede encontrar las direcciones más tarde buscando las secuencias interesantes de bytes en un hexdump más “normal” (salida de xxd first.bin).

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

Yo recomendaría el hexdump para descargar los archivos binarios al formato de texto y el kdiff3 para la visualización de diferencias.

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

El hexdiff es un programa diseñado para hacer exactamente lo que estás buscando.

Uso:

hexdiff file1 file2

Muestra el hexágono (y el ASCII de 7 bits) de los dos archivos uno encima del otro, con cualquier diferencia resaltada. Mira en man hexdiff los comandos para moverse en el archivo, y un simple q saldrá.

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

Puede que no responda estrictamente a la pregunta, pero uso esto para diferenciar binarios:

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

Imprime ambos archivos como valores hexadecimales y ASCII , un byte por línea, y luego usa la función diff de Vim para renderizarlos visualmente.

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

La herramienta de análisis de firmware binwalk también tiene esto como una característica a través de su -W/--hexdump opción de línea de comandos que ofrece opciones tales como mostrar sólo los 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

En el ejemplo de OP al hacer binwalk -W file1.bin file2.bin:

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

Puedes usar la herramienta gvimdiff que está incluida en el paquete vim-gui-common

sudo apt-get update

sudo apt-get install vim-gui-common

Entonces puedes comparar 2 archivos hexadecimales usando los siguientes comandos :

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

Eso es todo. Espero que eso ayude!

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

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

DHEX es más que otro editor hexadecimal: Incluye un modo de diferenciación, que puede ser usado para comparar fácil y convenientemente dos archivos binarios. Como está basado en ncurses y es temático, puede funcionar en cualquier número de sistemas y escenarios. Gracias a la utilización de registros de búsqueda, es posible seguir fácilmente los cambios en las diferentes iteraciones de los archivos.

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

El producto de código abierto en Linux (y todo lo demás) es Radare que provee radiff2 explícitamente para este propósito. Voté para cerrar esto porque yo mismo y otros tienen la misma pregunta, en la pregunta que haces

_ para cada byte diferente_

Eso es una locura, sin embargo. Porque como se pregunta, si insertas un byte en el primer byte del archivo, encontrarías que cada byte subsiguiente es diferente y por lo tanto la diferencia repetiría todo el archivo, para una diferencia real de un byte.

Un poco más práctico es radiff -O. El -O es para “Hacer la diferencia de código con todos los bytes en lugar de sólo los bytes de código de operación fijo”

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

Al igual que IDA Pro, Radare es una herramienta primaria para el análisis binario, también puede mostrar la diferencia delta con -d, o mostrar los bytes desmontados en lugar de hexadecimal con -D.

Sin embargo, si estás haciendo este tipo de preguntas, comprueba

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

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

BinDiff es una gran herramienta de interfaz para comparar archivos binarios que ha sido abierta recientemente.

Preguntas relacionadas

6
10
5
37
4