web-dev-qa-db-fra.com

Comment comparer les fichiers binaires sous Linux?

Je dois comparer deux fichiers binaires et obtenir le résultat sous la forme:

<fileoffset-hex> <fichier1 octets-hex> <fichier2 octets-hex>

pour chaque octet différent. Donc, si file1.bin est

  00 90 00 11

sous forme binaire et file2.bin est

  00 91 00 10

Je veux obtenir quelque chose comme

  00000001 90 91
  00000003 11 10

Y a-t-il un moyen de faire cela sous Linux? Je connais cmp -l, mais il utilise un système décimal pour les décalages et octal pour les octets, ce que je voudrais éviter.

287

Ceci imprimera le décalage et les octets au format hexadécimal:

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

Ou bien faites $1-1 pour que le premier offset imprimé commence à 0.

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

Malheureusement, strtonum() étant spécifique à GAWK, vous devrez utiliser une fonction de conversion octale à décimale pour les autres versions de awk, par exemple mawk. Par exemple,

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

Éclaté pour plus de lisibilité:

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)
          }'
167
Dennis Williamson

Comme ~ charlatan fit remarquer:

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

Et alors

 % diff b1.hex b2.hex

ou

 % vimdiff b1.hex b2.hex
159
akira

diff + xxd

Essayez diff dans la combinaison suivante de substitution de processus zsh/bash et colordiff dans l'interface de ligne de commande:

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

Où:

  • -y affiche les différences côte à côte (facultatif)
  • xxd est un outil CLI permettant de créer une sortie hexdump du fichier binaire
  • ajoutez -W200 à diff pour une sortie plus large (de 200 caractères par ligne)

colordiff + xxd

Si vous avez colordiff, il peut coloriser la sortie diff, par exemple:

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

Sinon, installez via: Sudo apt-get install colordiff.

Exemple de sortie:

 binary file output in terminal - diff -y <(xxd foo1.bin) <(xxd foo2.bin) | colordiff

vimdiff + xxd

Vous pouvez également utiliser vimdiff, par exemple.

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

Astuces:

  • si les fichiers sont trop volumineux, ajoutez une limite (par exemple, -l1000) pour chaque xxd
77
kenorb

Il existe un outil appelé DHEX qui peut faire l'affaire, et un autre outil appelé VBinDiff .

Pour une approche strictement en ligne de commande, essayez JDIFF .

52
njd

Méthode qui fonctionne pour l'ajout/la suppression d'octets

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

Générez un scénario de test avec une seule suppression de l'octet 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

Sortie:

64d63
<  40

Si vous souhaitez également voir la version ASCII du caractère:

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

bdiff file1 file2

Sortie:

64d63
<   40   @

Testé sur Ubuntu 16.04.

Je préfère od à xxd parce que:

  • il est POSIX , xxd n'est pas (livré avec Vim)
  • a le -An pour supprimer la colonne d'adresse sans awk.

Explication de la commande:

  • -An supprime la colonne d'adresse. C'est important sinon toutes les lignes seraient différentes après l'ajout/le retrait d'un octet.
  • -w1 met un octet par ligne, pour que diff puisse le consommer. Il est crucial d’avoir un octet par ligne, sinon chaque ligne après une suppression deviendrait déphasée et différerait. Malheureusement, ce n'est pas POSIX, mais présent dans GNU.
  • -tx1 est la représentation souhaitée, remplacez-la par une valeur possible, à condition de conserver un octet par ligne.
  • -v empêche l'abréviation de répétition astérisque * qui pourrait interférer avec le diff
  • paste -d '' - - rejoint toutes les deux lignes. Nous en avons besoin car l'hex et ASCII vont dans des lignes adjacentes séparées. Extrait de: https://stackoverflow.com/questions/8987257/concatenating-every-other-line-with-the-next
  • nous utilisons la parenthèse () pour définir bdiff au lieu de {} pour limiter la portée de la fonction interne f, voir aussi: https://stackoverflow.com/questions/8426077/how-to-define-a-function-inside-another -function-in-bash

Voir également:

Réponse courte

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

Lorsque vous utilisez hexdumps et text diff pour comparer des fichiers binaires, en particulier xxd, les ajouts et suppressions d'octets deviennent des modifications dans l'adressage, ce qui peut rendre la lecture difficile. Cette méthode indique à xxd de ne pas afficher les adresses et de ne générer qu'un seul octet par ligne, ce qui indique à son tour quels octets ont été modifiés, ajoutés ou supprimés. Vous pourrez trouver les adresses plus tard en recherchant les séquences d'octets intéressantes dans un hexdump plus "normal" (sortie de xxd first.bin).

13
Evgeny

Je recommanderais hexdump pour vider les fichiers binaires au format texte et kdiff3 pour les diff.

hexdump myfile1.bin > myfile1.hex
hexdump myfile2.bin > myfile2.hex
kdiff3 myfile1.hex myfile2.hex
11
BugoK

La hexdiff est un programme conçu pour faire exactement ce que vous recherchez.

Usage:

hexdiff file1 file2

Il affiche le format hexadécimal (et ASCII 7 bits) des deux fichiers superposés, avec les différences mises en évidence. Regardez man hexdiff pour les commandes à déplacer dans le fichier, et un simple q quittera.

5
Mick

Cela ne répond peut-être pas strictement à la question, mais je l'utilise pour les fichiers binaires différents:

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

Il imprime les deux fichiers sous forme de valeurs hexadécimales et ASCII , un octet par ligne, puis utilise la fonction de diff de Vim pour les rendre visuellement.

3

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

DHEX est un autre éditeur hexadécimal: il comprend un mode diff, qui permet de comparer facilement et commodément deux fichiers binaires. Comme il est basé sur ncurses et qu'il est possible de les utiliser, il peut être exécuté sur un nombre quelconque de systèmes et de scénarios. Avec son utilisation des journaux de recherche, il est possible de suivre facilement les modifications apportées à différentes itérations de fichiers.

0
Vincent Vega

Vous pouvez utiliser gvimdiff outil inclus dans vim-gui-common package

Sudo apt-get update

Sudo apt-get installer vim-gui-common

Ensuite, vous pouvez comparer 2 fichiers hexadécimaux en utilisant les commandes suivantes:

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

C'est tout. J'espère que l'aide!

0
craken