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