14 June 2010

(Linux,Windows)バイナリファイルの差分(比較)表示

WindowsやLinuxでバイナリファイルの差分表示をさせると、どちらも見栄えが悪い…。Windowsは16進数で表示してくれているけど、表示が冗長過ぎる。Linuxはアドレスが10進数、データが8進数とバイナリエディタで修正するときにすぐには使えそうに無い表示…。

どうにかならないものかと。

■ Windowsの場合

S:\theme>comp org\uxtheme.dll mod\uxtheme.dll org\uxtheme.dll と mod\uxtheme.dll を比較しています... オフセット 148 で比較エラーがあります ファイル1 = 8B ファイル2 = D4 オフセット 149 で比較エラーがあります ファイル1 = A5 ファイル2 = 7D オフセット 1C020 で比較エラーがあります ファイル1 = 81 ファイル2 = 33 オフセット 1C021 で比較エラーがあります ファイル1 = EC ファイル2 = C0 オフセット 1C022 で比較エラーがあります ファイル1 = 84 ファイル2 = C9 オフセット 1C023 で比較エラーがあります ファイル1 = 0 ファイル2 = C2 オフセット 1C024 で比較エラーがあります ファイル1 = 0 ファイル2 = 4 ほかのファイルを比較しますか (Y/N)?

■ Linuxの場合

$ cmp -l org/uxtheme.dll mod/uxtheme.dll 329 213 324 330 245 175 114721 201 63 114722 354 300 114723 204 311 114724 0 302 114725 0 4

■ Linuxでの表示をすっきりしたものにするスクリプトを作成

cmp2hex.pl
#!/usr/bin/perl use strict; use warnings; my (@arrBuf, @arrItem, $strBuf, $strItem); @arrBuf = <STDIN>; foreach $strBuf (@arrBuf){ $strBuf =~ s/\n//g; # 行末の改行を削除 $strBuf =~ s/\s+/ /g; # 連続した空白を1つの空白に置換 $strBuf =~ s/^\s//g; # 行頭の空白を削除 $strBuf =~ s/\s$//g; # 行末の空白を削除 # printf("[%s] :", $strBuf); # デバッグ表示(オリジナルデータを表示) @arrItem = split(/\s/, $strBuf); if($#arrItem != 2){ printf("(Error:データ数が3でない行です) \"%s\"\n", $strBuf); next; } printf("%06X %02X %02X\n", $arrItem[0], oct($arrItem[1]), oct($arrItem[2])); }

このスクリプトをパイプで通すと…

$ cmp -l org/uxtheme.dll mod/uxtheme.dll | cmp2hex.pl 000149 8B D4 00014A A5 7D 01C021 81 33 01C022 EC C0 01C023 84 C9 01C024 00 C2 01C025 00 04

こういうのが欲しかったんです…

■ cmpのプログラム自体を改変してしまう

本当は、cmpのソースコードを修正すればいいんですけどね。 他のソフトから、cmpの結果が呼び出されている可能性がありますので、標準コマンドの出力様式を変えるなんてできませんけどね…

diffutilsパッケージのソースコードをダウンロードして、次の箇所を修正してビルドする。

cmp.c の516行あたり
if (!opt_print_bytes) { /* See POSIX 1003.1-2001 for this format. */ /* printf ("%*s %3o %3o\n", offset_width, byte_num, c0, c1); */ printf ("%06X %02X %02X\n", byte_number, c0, c1); }

■ 参考:他のバイナリファイル比較ソフト (Linux版)

vbindiff (コンソールプログラム)

20100614-vbindiff.png


xdelta (バイナリファイルのパッチ作成・適用プログラム)
パッチなので、人間の目で見てもわけが分かりません…

# xdelta delta -0 org/uxtheme.dll mod/uxtheme.dll /tmp/delta.tmp # hexdump /tmp/delta.tmp 0000000 5825 5a44 3030 2534 0000 0000 0b00 0b00 0000010 0000 0000 0000 0000 0000 0000 0000 0000 0000020 7875 6874 6d65 2e65 6c64 756c 7478 6568 0000030 656d 642e 6c6c 7dd4 c033 c2c9 0004 8000 0000040 0003 0100 c608 451e 19c6 f15a dff4 a755 0000050 6a3b 8282 80e5 0fa0 0201 280c 6170 6374 0000060 2068 6164 6174 2d29 dd30 f855 f023 7e00 0000070 5626 958e 9f2f 07ba 0101 750b 7478 6568 0000080 656d 642e 6c6c bf63 55df a25d 5a07 d677 0000090 8277 3c9c d0cc a080 000f 0500 0001 02c8 00000a0 0000 0102 02ca fdd6 0006 0500 a501 0780 00000b0 9fdb 0008 0000 253d 4458 305a 3430 0025 00000bf