web-dev-qa-db-ja.com

Linuxでバイナリファイルを比較する方法

2つのバイナリファイルを比較して出力を次の形式で取得する必要があります。

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

異なるバイトごとに。 file1.bin

  00 90 00 11

バイナリ形式で、file2.bin

  00 91 00 10

こんなものを手に入れたい

  00000001 90 91
  00000003 11 10

Linuxでこれを行う方法はありますか?私はcmp -lについて知っていますが、オフセットには10​​進法を使い、バイトには8進法を使いますが、避けたいのです。

これはオフセットとバイトを16進数で表示します。

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

または$1-1を実行して、最初の印刷オフセットを0から始めます。

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

残念なことに、strtonum()はGAWK特有のものであるため、他のバージョンのawk(たとえばmawk)では、8進数から10進数への変換関数を使用する必要があります。例えば、

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

読みやすくするために分割しました。

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

〜quackが指摘したように、

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

その後

 % diff b1.hex b2.hex

または

 % vimdiff b1.hex b2.hex
160
akira

diff + xxd

以下のzsh/bashプロセス置換の組み合わせでdiffを試してください。

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

どこで:

  • -yは、違いを並べて表示します(オプション)。
  • xxdは、バイナリファイルのhexdump出力を作成するためのCLIツールです。
  • 幅の広い出力(1行あたり200文字)の場合は、diff-W200を追加します。
  • 色については、以下のようにcolordiffを使用してください。

colordiff + xxd

colordiffなら、diffの出力を色付けできます。

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

それ以外の場合はSudo apt-get install colordiff経由でインストールしてください。

出力例:

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

vimdiff + xxd

vimdiffを使うこともできます。

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

ヒント:

  • ファイルが大きすぎる場合は、それぞれのxxdに制限(例:-l1000)を追加してください
80
kenorb

仕事をするかもしれない DHEX と呼ばれるツールがあります、そして と呼ばれる別のツールがありますVBinDiff .

厳密なコマンドラインアプローチの場合は、 JDIFF を試してください。

52
njd

バイト追加/削除に有効なメソッド

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

64バイトを1回削除してテストケースを生成します。

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

出力:

64d63
<  40

ASCIIバージョンのキャラクターも見たい場合は、

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

bdiff file1 file2

出力:

64d63
<   40   @

Ubuntu 16.04でテスト済み。

私はodname__よりxxdname__を好みます。

  • はPOSIX ですが、xxdname__はそうではありません(Vimに付属)
  • awkname__なしで住所列を削除するための-Anがあります。

コマンドの説明

  • -Anはアドレス列を削除します。そうでなければすべての行がバイトの追加/削除の後で異なるだろうこれは重要です。
  • -w1は1行に1バイトを入れるので、diffはそれを消費することができます。 1行に1バイト、または削除後のすべての行が位相がずれて異なる場合があります。残念ながら、これはPOSIXではなく、GNUに存在します。
  • -tx1はあなたが望む表現です、あなたが1行につき1バイトを保つ限り、どんな可能な値にでも変更してください。
  • -vはアスタリスクの繰り返しの省略形*を防ぎます。
  • paste -d '' - -は2行ごとに結合します。これは、hexとASCIIが別々の隣接行に入るために必要です。 https://stackoverflow.com/questions/8987257/concatenating-every-other-line-with-the-next から取得
  • 内部関数bdiffname__の範囲を制限するために()の代わりにfname__を定義するために括弧{}を使用します。 https://stackoverflow.com/questions/8426077/how-to-define-a-functionも参照してください。インバースイン関数

また見なさい:

短い答え

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

バイナリファイル、特にxxdを比較するためにhexdumpsとtext diffを使うとき、バイトの追加と削除はアドレス指定のシフトとなり、見るのが難しくなります。このメソッドは、アドレスを出力せず、1行に1バイトだけ出力するようにxxdに指示します。これは、変更、追加、または削除されたバイトを正確に示します。後でもっと普通の16進ダンプ(xxd first.binの出力)で興味深いバイト列を検索することでアドレスを見つけることができます。

13
Evgeny

バイナリファイルをテキスト形式にダンプするにはhexdumpを、差分表示にはkdiff3をお勧めします。

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

hexdiffはあなたが探しているものを正確に実行するように設計されたプログラムです。

使用法:

hexdiff file1 file2

2つのファイルの16進数(および7ビットASCII)が上下に表示され、相違点が強調表示されます。ファイル内を移動するコマンドがman hexdiffで見つかると、単純なqが終了します。

5
Mick

厳密には質問に答えないかもしれませんが、私はこれを差分バイナリのために使用します。

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

両方のファイルを16進数と ASCII で1行に1バイトずつ出力し、それからそれらを視覚的にレンダリングするためにVimのdiff機能を使います。

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

DHEXは、単なる16進エディタではありません。diffモードが含まれています。これを使用すると、2つのバイナリファイルを簡単かつ便利に比較できます。それはncursesに基づいていてテーマにしやすいので、それは任意の数のシステムとシナリオで動くことができます。検索ログを利用することで、さまざまなファイルの繰り返しの変更を簡単に追跡できます。

0
Vincent Vega

vim-gui-commonパッケージに含まれているgvimdiffツールを使用できます

Sudo apt-getアップデート

Sudo apt-get install vim-gui-common

その後、次のコマンドを使用して2つの16進数ファイルを比較できます。

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

Thaさんです。助けてくださいね!

0
craken

ファームウェア分析ツールbinwalkには、 -W/--hexdumpコマンドラインオプション の機能としてこれがあり、異なるバイトのみを表示するなどのオプションを提供します。

    -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

binwalk -W file1.bin file2.binを実行するときのOPの例:

binwalk -W file1.bin file2.bin

0
phk