Wie vergleiche ich Binärdateien unter Linux?


304

Ich muss zwei Binärdateien vergleichen und die Ausgabe in der Form erhalten:

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

für jedes andere Byte. Also wenn file1.binja

  00 90 00 11

in binärer Form und file2.binist

  00 91 00 10

Ich möchte so etwas bekommen

  00000001 90 91
  00000003 11 10

Gibt es eine Möglichkeit, dies unter Linux zu tun? Ich weiß, cmp -laber es verwendet ein Dezimalsystem für Offsets und Oktal für Bytes, die ich vermeiden möchte.


9
Sie suchen im Grunde nach "binären Diff". Ich kann mir einige wirklich hässliche Kommandozeilen- od
Einzeiler

2
@ Quack Quijote: Was ist hässlich an einem Einzeiler? ;)
Bobby

xdelta.org funktioniert ganz gut. Vielleicht lohnt es sich, einen Blick darauf zu werfen.
Thatjuan

Da Sie diese Frage nicht beantworten können (da Sie kein Benutzer sind), stimme ich für das Schließen. Ein hier ausdrücklich angefordertes binäres Diff ist überhaupt nicht nützlich, und ich bin der Ansicht, dass Sie etwas Nützliches wollen, wenn Sie ein Byte am Anfang der Datei einfügen, sollten alle Bytes als unterschiedlich markiert sein? Ohne das zu wissen, ist dies einfach zu vage.
Evan Carroll

2
@EvanCarroll Wenn Sie der Meinung sind, dass die Frage nicht zum Thema gehört, warum beantworten Sie sie dann?
DavidPostill

Antworten:


174

Dies gibt den Offset und die Bytes in hexadezimaler Form aus:

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

Oder lassen Sie $1-1den ersten gedruckten Versatz bei 0 beginnen.

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

Leider strtonum()ist GAWK-spezifisch. Daher müssen Sie für andere Versionen von awk - z. B. mawk - eine Konvertierungsfunktion von Oktal zu Dezimal verwenden. Zum Beispiel,

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

Aus Gründen der Lesbarkeit aufgeschlüsselt:

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

3
@gertvdijk: strtonumist GAWK-spezifisch. Ich glaube Ubuntu hat vorher GAWK als Standard verwendet, aber irgendwann auf umgestellt mawk. In jedem Fall kann GAWK installiert und auf die Standardeinstellungen gesetzt werden (siehe auch man update-alternatives). In meiner aktualisierten Antwort finden Sie eine Lösung, die nicht erforderlich ist strtonum.
Dennis Williamson

Warum nicht einfach die sha256sum beider Dateien vergleichen?
Rodrigo

1
@ Rodrigo: Das und verschiedene andere Methoden zeigen nur, ob sich die Dateien unterscheiden. Meine Antwort entspricht der Anforderung des OP, die Unterschiede tatsächlich aufzuzeigen.
Dennis Williamson

Na sicher! Tut mir leid, ich war so besorgt wegen MEINEM Problem, dass ich kaum die OPs gelesen habe. Danke.
Rodrigo

166

Als ~ quack darauf hingewiesen:

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

Und dann

 % diff b1.hex b2.hex

oder

 % vimdiff b1.hex b2.hex

70
In Bash: diff <(xxd b1) <(xxd b2)aber das Ausgabeformat von diesem (oder Ihrem) ist bei weitem nicht das, wonach das OP gefragt hat.
Dennis Williamson

6
mit vimdiff werden die bytes in den zeilen, in denen sich die beiden 'files' unterscheiden,
farblich hervorgehoben

Oh, warum habe ich nicht daran gedacht? Und ich bin mir sicher, dass ich diese Technik auch in der Vergangenheit angewendet habe.
30.03.10 um 17:37

1
Das hat bei mir sehr gut funktioniert (mit opendiffOS X statt vimdiff) - die Standardansicht xxdhält die Diff-Engine auf dem Laufenden, indem sie Byte für Byte vergleicht. Mit normalem (rohem) Hex, das einfach in eine Spalte passt fold, diffwürde ich versuchen, zufälliges Material in den Dateien, die ich verglichen habe, zu falten / zu gruppieren.
Natevw

1
Dieser Befehl eignet sich nicht für das Entfernen von Byteadditionen, da jede nachfolgende Zeile falsch ausgerichtet ist und von als geändert angesehen wird diff. Die Lösung besteht darin, 1 Byte pro Zeile einzufügen und die von John Lawrence Aspden und mir vorgeschlagene Adressenspalte zu entfernen .
Ciro Santilli新疆改造中心法轮功六四事件

98

diff + xxd

Probieren Sie diffdie folgende Kombination aus zsh / bash-Prozessersetzung aus:

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

Wo:

  • -y Zeigt die Unterschiede nebeneinander an (optional).
  • xxd ist ein CLI-Tool zum Erstellen einer Hexdump-Ausgabe der Binärdatei.
  • Add -W200to difffür eine breitere Ausgabe (mit 200 Zeichen pro Zeile).
  • Verwenden Sie für Farben colordiffdie folgenden Angaben.

colordiff + xxd

Wenn Sie haben colordiff, kann es die diffAusgabe einfärben , zB:

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

Andernfalls installieren über: sudo apt-get install colordiff.

Beispielausgabe:

Binärdateiausgabe im Terminal - diff -y <(xxd foo1.bin) <(xxd foo2.bin) |  Colordiff

vimdiff + xxd

Sie können auch vimdiffz

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

Hinweise:

  • Wenn die Dateien zu groß sind, fügen Sie jeweils ein Limit hinzu (z. B. -l1000)xxd

11
Befehl kann vereinfacht werden als colordiff -y <(xxd foo1.bin) <(xxd foo2.bin).
Golem

3
Wenn Sie keinen Farbton haben, funktioniert dies auch ohne Farben:diff -y <(xxd foo1.bin) <(xxd foo2.bin)
Rock Lee,

5
Wenn Sie nur wissen möchten, ob beide Dateien tatsächlich identisch sind, können Sie den Schalter -qoder verwenden --brief, der die Ausgabe nur anzeigt, wenn sich die Dateien unterscheiden.
Stefan van den Akker

1
erstelle dazu eine funktion xxddiffmit:xxddiff() ( f() ( xxd "$1" ; ); diff -y <(f "$1") <(f "$2") | colordiff; )
rubo77 14.11.16

2
groß! nach wie vor, diff -u <(xxd tinga.tgz) <(xxd dec.out.tinga.tgz) | vim - wird gut enoug einen Job tun
Ribamar

56

Es gibt ein Tool namens DHEX, das die Arbeit erledigen kann, und es gibt ein anderes Tool namens VBinDiff .

Versuchen Sie es mit jojodiff , um eine strikte Befehlszeilenmethode zu erhalten .


8
DHEX ist großartig. Vergleichen von Binärdateien ist das, was Sie tun möchten. Wenn Sie zwei Dateien eingeben, gelangen Sie direkt zu einer vergleichenden Ansicht, in der Unterschiede hervorgehoben werden. Sie können problemlos zum nächsten Unterschied wechseln. Es ist auch in der Lage, mit großen Terminals zu arbeiten, was auf Breitbildmonitoren sehr nützlich ist.
Marcin

7
Ich bevorzuge VBinDiff. DHEX verwendet die CPU auch im Leerlauf, ich denke, es wird die ganze Zeit neu gezeichnet oder so. VBinDiff funktioniert jedoch nicht mit breiten Terminals. Bei breiten Terminals werden die Adressen jedoch ohnehin komisch, da Sie mehr als 16 Bytes pro Zeile haben.
Janus Troelsen

1
Mit vbindiff können wir die Datei tatsächlich bearbeiten, danke!
Aquarius Power

2
@DanielBeauyat komprimierte Dateien werden sich völlig unterscheiden, nachdem Sie auf das erste unterschiedliche Byte gestoßen sind. Die Ausgabe ist wahrscheinlich nicht nützlich.
Mark Ransom

2
@ 1111161171159459134 jdiff ist Teil einer "Suite" von Programmen zum Synchronisieren und Patchen der von jdiff gefundenen Unterschiede. Aber, wie Mark Ransom sagte, wäre das bei komprimierten Dateien im Allgemeinen nicht sinnvoll. Die Ausnahme bilden "synchronisierbare" komprimierte Formate (wie die von gzip --rsyncable erzeugten), bei denen kleine Unterschiede in den unkomprimierten Dateien eine begrenzte Auswirkung auf die komprimierte Datei haben sollten.
Hmijail

27

Methode, die für das Hinzufügen / Löschen von Bytes funktioniert

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

Generieren Sie einen Testfall mit einer einzelnen Entfernung von 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

Ausgabe:

64d63
<  40

Wenn Sie auch die ASCII-Version des Zeichens sehen möchten:

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

bdiff file1 file2

Ausgabe:

64d63
<   40   @

Getestet unter Ubuntu 16.04.

Ich ziehe es odüber , xxdweil:

  • es ist POSIX , xxdist nicht (kommt mit Vim)
  • muss die -Anadressenspalte ohne entfernen awk.

Befehlserklärung:

  • -AnEntfernt die Adressenspalte. Dies ist wichtig, da sich sonst alle Zeilen nach dem Hinzufügen / Entfernen eines Bytes unterscheiden würden.
  • -w1setzt ein Byte pro Zeile, so dass diff es verbrauchen kann. Es ist von entscheidender Bedeutung, ein Byte pro Zeile zu haben, da sonst jede Zeile nach dem Löschen außer Phase gerät und sich unterscheidet. Leider ist dies kein POSIX, sondern in GNU vorhanden.
  • -tx1 Bei der gewünschten Darstellung ändern Sie den Wert auf einen beliebigen Wert, solange Sie 1 Byte pro Zeile beibehalten.
  • -vVerhindert die Abkürzung für *die Sternchenwiederholung, die das Diff stören könnte
  • paste -d '' - -Verbindet alle zwei Zeilen. Wir brauchen es, weil Hex und ASCII in separate benachbarte Zeilen gehen. Entnommen aus: https://stackoverflow.com/questions/8987257/catenating-every-other-line-with-the-next
  • Wir verwenden Klammern (), um den Umfang der inneren Funktion zu definieren, bdiffanstatt ihn {}einzuschränken f. Siehe auch: https://stackoverflow.com/questions/8426077/how-to-define-a-function-inside-another-function-in-bash

Siehe auch:


13

Kurze Antwort

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

Insbesondere bei Verwendung von Hexdumps und Text Diff zum Vergleichen von Binärdateien xxdkommt es durch das Hinzufügen und Entfernen von Bytes zu Adressverschiebungen, die die Anzeige möglicherweise erschweren. Diese Methode weist xxd an, keine Adressen auszugeben und nur ein Byte pro Zeile auszugeben, wodurch genau angezeigt wird, welche Bytes geändert, hinzugefügt oder entfernt wurden. Sie können die Adressen später finden, indem Sie in einem "normalen" Hexdump (Ausgabe von xxd first.bin) nach den interessanten Folgen von Bytes suchen .


(Natürlich kann man diffanstelle von verwenden vimdiff.)
VasyaNovikov

11

Ich empfehle hexdump zum Speichern von Binärdateien im Textformat und kdiff3 zum Anzeigen von Unterschieden.

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

2
Auch hier in Bash kdiff3 <(hexdump myfile1.bin) <(hexdump myfile2.bin)ohne die Notwendigkeit, Dateien zu erstellen myfile1.hexund myfile2.hex.
Hastur

5

Das hexdiffist ein Programm, das genau das macht, wonach Sie suchen.

Verwendungszweck:

hexdiff file1 file2

Es zeigt das Hexadezimal (und 7-Bit-ASCII) der beiden Dateien übereinander an, wobei alle Unterschiede hervorgehoben sind. Suchen Sie man hexdiffnach den Befehlen, die in der Datei verschoben werden sollen, und ein einfacher qBefehl wird beendet.


4
Aber es macht einen ziemlich schlechten Job, wenn es um den Vergleichsteil geht. Wenn Sie einige Bytes in eine Datei einfügen, werden alle Bytes danach als Änderungen markiert
Murmel

und hexdiff ist unter Ubuntu 16.4
rubo77

1
@Murmel, obwohl ich damit einverstanden bin, ist es nicht das, was hier gefragt wird?
Evan Carroll

@EvanCarroll wahr, und daher habe ich einen Kommentar (nur) und nicht negativ bewertet
Murmel

Ich habe auch Mick nicht abgewählt, aber ich stimme dir zu und habe hier superuser.com/a/1373977/11116 geantwortet, weil es wahrscheinlich ist, dass diese schlechte Frage reformiert oder geschlossen wird.
Evan Carroll

3

Es kann sein, dass die Frage nicht genau beantwortet wird, aber ich verwende dies für verschiedene Binärdateien:

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

Es druckt beide Dateien als Hex- und ASCII- Werte aus, ein Byte pro Zeile, und verwendet dann die Diff-Funktion von Vim, um sie visuell darzustellen.


0

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

DHEX ist mehr als nur ein Hex-Editor: Es enthält einen Diff-Modus, mit dem zwei Binärdateien einfach und bequem verglichen werden können. Da es auf ncurses basiert und themenorientiert ist, kann es auf einer beliebigen Anzahl von Systemen und Szenarien ausgeführt werden. Durch die Verwendung von Suchprotokollen ist es möglich, Änderungen in verschiedenen Iterationen von Dateien einfach zu verfolgen.


Willkommen bei SuperUser! Obwohl diese Software wie sieht es könnte die OP das Problem, reine Werbung lösen , ist stark im Netzwerk - Stack Exchange - verpönt. Wenn Sie mit dem Editor dieser Software verbunden sind, geben Sie dies bitte bekannt. Und versuchen Sie, Ihren Beitrag so umzuschreiben, dass er weniger wie ein Werbespot aussieht. Danke.
Nathan.Eilisha Shiraini

Ich bin in keiner Weise mit dhex verbunden. Ich habe die Beschreibung des Autors in den Beitrag kopiert, da es eine Mindestlänge für Beiträge gibt
Vincent Vega,


0

Sie können das Tool gvimdiff verwenden, das im Paket vim-gui-common enthalten ist

sudo apt-get update

sudo apt-get installiere vim-gui-common

Dann können Sie 2 hexadezimale Dateien mit folgenden Befehlen vergleichen:

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

Das ist alles. Hoffe die Hilfe!


0

Das Firmware-Analysetool binwalkhat dies auch als eine Funktion über die Befehlszeilenoption -W/ --hexdump, die Optionen bietet, mit denen nur die unterschiedlichen Bytes angezeigt werden:

    -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

Im Beispiel von OP binwalk -W file1.bin file2.bin:

binwalk -W datei1.bin datei2.bin



-2

Das Go-to-Open-Source-Produkt unter Linux (und allem anderen) ist Radare , das radiff2explizit für diesen Zweck bereitgestellt wird . Ich habe dafür gestimmt, dies zu schließen, weil ich und andere in der von Ihnen gestellten Frage dieselbe Frage haben

für jedes andere Byte

Das ist aber verrückt. Denn wenn Sie, wie gefragt, ein Byte am ersten Byte in die Datei einfügen, ist jedes nachfolgende Byte anders und der Diff würde die gesamte Datei wiederholen, um eine tatsächliche Differenz von einem Byte zu erhalten.

Etwas praktischer ist radiff -O. Das -Oist für "" Code mit allen Bytes anstelle nur der festen Opcode-Bytes unterscheiden. ""

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

Wie IDA Pro ist Radare ein primäres Werkzeug für die Binäranalyse. Sie können auch Delta-Differenzen mit -danzeigen oder die disassemblierten Bytes anstelle von Hex mit anzeigen -D.

Wenn Sie diese Art von Fragen stellen, lesen Sie weiter

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.