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

Comment puis-je comparer des fichiers binaires sous Linux ?

Je dois comparer deux fichiers binaires et obtenir la sortie sous la forme :

<fichier-hexage/décalage > <fichier1-octet-hexage/décalage > <fichier2-octet-hexage/décalage >

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

00 90 00 11

sous forme binaire et que 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.

Réponses (14)

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

Cela imprimera l'offset et les octets en hexadécimal :

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

Ou 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() est spécifique à GAWK, donc pour d'autres versions de awk- par exemple, mawk-you devra utiliser une fonction de conversion octal-décimal. 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)}'

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

Comme ~quack l'a fait remarquer :

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

Et puis

% diff b1.hex b2.hex

ou

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

diff + xxd

Essayez diff dans la combinaison suivante de substitution de processus zsh/bash :

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

Où :

  • -y vous montre les différences côte à côte (facultatif).
  • xxd est un outil CLI pour créer une sortie hexadécimale du fichier binaire.
  • Ajoutez -W200 à diff pour une sortie plus large (de 200 caractères par ligne).
  • Pour les couleurs, utilisez colordiff comme indiqué ci-dessous.

colordiff + xxd

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

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

Sinon, installez via : sudo apt-get install colordiff. Vous pouvez également utiliser vimdiff, par exemple :

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

Conseils :

  • si les fichiers sont trop gros, ajoutez une limite (par exemple xxd) pour chaque vimdiff
60
60
60
2010-03-29 15:41:30 +0000

Il existe un outil appelé DHEX qui peut faire le travail, et un autre outil appelé VBinDiff .

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

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

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érer un cas 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 voulez é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 :

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

Explication de la commande :

  • -An supprime la colonne d'adresse. Ceci est important sinon toutes les lignes seraient différentes après l'ajout / la suppression d'un octet.
  • -w1 met un octet par ligne, de sorte que diff puisse le consommer. Il est crucial d'avoir un octet par ligne, sinon toutes les lignes après une suppression seraient déphasées et différentes. Malheureusement, ce n'est pas POSIX, mais présent dans GNU.
  • -tx1 est la représentation que vous voulez, changez à n'importe quelle valeur possible, tant que vous gardez 1 octet par ligne.
  • -v empêche l'abréviation de répétition d'astérisque * qui pourrait interférer avec la diff
  • paste -d '' - - joint toutes les deux lignes. Nous en avons besoin car l'hexagone et l'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 aussi :

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

Réponse brève

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

Lorsque l'on utilise des fichiers hexadécimaux et des différences de texte pour comparer des fichiers binaires, en particulier xxd, les ajouts et les retraits d'octets se transforment en décalages d'adressage qui peuvent rendre la comparaison difficile. Cette méthode indique à xxd de ne pas sortir d'adresses et de ne sortir qu'un octet par ligne, ce qui permet de voir exactement quels octets ont été modifiés, ajoutés ou supprimés. Vous pouvez trouver les adresses plus tard en recherchant les séquences d'octets intéressantes dans un hexdump plus “normal” (sortie de xxd first.bin).

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

Je recommande le format hexdump pour le transfert de fichiers binaires au format textuel et kdiff3 pour la visualisation des différences.

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

Le hexdiff est un programme conçu pour faire exactement ce que vous cherchez. Utilisation :

hexdiff file1 file2

Il affiche l'hexagone (et l'ASCII 7 bits) des deux fichiers l'un au-dessus de l'autre, avec les différences éventuelles mises en évidence. Regardez man hexdiff pour les commandes de déplacement dans le fichier, et un simple q quittera.

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

Il se peut qu'il ne réponde pas strictement à la question, mais je l'utilise pour différencier les binaires :

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 comme des valeurs hex et ASCII , un octet par ligne, et utilise ensuite la fonction de différenciation de Vim pour les rendre visuellement.

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

L'outil d'analyse du microprogramme binwalk dispose également de cette fonction grâce à son option de ligne de commande -W/--hexdump qui offre des options telles que l'affichage des différents octets uniquement :

-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

Dans l'exemple d'OP en faisant binwalk -W file1.bin file2.bin :

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

Vous pouvez utiliser l'outil gvimdiff qui est inclus dans le paquet vim-gui-common

sudo apt-get update

sudo apt-get install 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 cela vous aidera !

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

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

DHEX est plus qu'un simple éditeur hexadécimal : il comprend un mode diff, qui peut être utilisé pour comparer facilement et commodément deux fichiers binaires. Comme il est basé sur ncurses et qu'il est thématique, il peut fonctionner sur un nombre illimité de systèmes et de scénarios. Grâce à l'utilisation de journaux de recherche, il est possible de suivre facilement les changements dans les différentes itérations de fichiers.

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

Le produit “go to open source” sur Linux (et tout le reste) est Radare qui fournit radiff2 explicitement à cette fin. J'ai voté pour clore ce dossier parce que moi-même et d'autres avons la même question, dans la question que vous posez

pour chaque octet différent

C'est pourtant insensé. Parce que comme demandé, si vous insérez un octet au premier octet du fichier, vous constaterez que chaque octet suivant est différent et la différence répétera tout le fichier, pour une différence réelle d'un octet.

Un peu plus pratique est radiff -O. Le -O est pour “"Do code diffing with all bytes instead of 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

Comme IDA Pro, Radare est un outil primaire pour l'analyse binaire, vous pouvez aussi montrer la différence delta avec -d, ou afficher les octets désassemblés au lieu de l'hex avec -D. Si vous vous posez ce genre de questions, consultez

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

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

BinDiff est un excellent outil d'interface utilisateur pour comparer les fichiers binaires qui ont été ouverts récemment.