Posted at

普通の Linux 環境で手軽にバイナリファイルを編集する (dd, vim)

More than 3 years have passed since last update.


テスト用ファイル

ちょうど手元にあった PPPoE の pcap ファイルから CHAP の部分を抜粋したもの

PPPoE のユーザ名 (hogehoge@one.ocn.ne.jp) をマスクする目的で書き換えてみる。

hogehoge の部分を xxxxxxxx のようにどうでもいい文字列で埋める。

編集したいファイルが大きい場合、Vim を使う方法ではメモリ消費が激しいので避ける。


dd でバイナリ編集

編集する場所を確認するため、一度 hexdump で中身を調べる

$ hexdump -C pppoe.cap

00000000 0a 0d 0d 0a 34 00 00 00 4d 3c 2b 1a 01 00 00 00 |....4...M<+.....|
00000010 ff ff ff ff ff ff ff ff 04 00 0e 00 45 64 69 74 |............Edit|
00000020 63 61 70 20 31 2e 31 30 2e 33 00 00 00 00 00 00 |cap 1.10.3......|
00000030 34 00 00 00 01 00 00 00 20 00 00 00 01 00 00 00 |4....... .......|
00000040 ff ff 00 00 09 00 01 00 06 00 00 00 00 00 00 00 |................|
00000050 20 00 00 00 06 00 00 00 5c 00 00 00 00 00 00 00 | .......\.......|
00000060 c8 11 05 00 2e 6f d1 55 3c 00 00 00 3c 00 00 00 |.....o.U<...<...|
00000070 00 16 3e 5a be 76 00 12 e2 70 c9 3e 88 64 11 00 |..>Z.v...p.>.d..|
00000080 47 55 00 1a c2 23 01 01 00 18 10 bc 71 90 18 fe |GU...#......q...|
00000090 6e 3f bd 12 07 89 66 85 68 3b 69 42 41 53 00 00 |n?....f.h;iBAS..|
000000a0 00 00 00 00 00 00 00 00 00 00 00 00 5c 00 00 00 |............\...|
000000b0 06 00 00 00 64 00 00 00 00 00 00 00 c8 11 05 00 |....d...........|
000000c0 1c 70 d1 55 41 00 00 00 41 00 00 00 00 12 e2 70 |.p.UA...A......p|
000000d0 c9 3e 00 16 3e 5a be 76 88 64 11 00 47 55 00 2d |.>..>Z.v.d..GU.-|
000000e0 c2 23 02 01 00 2b 10 65 02 01 45 0e fd dd 19 6e |.#...+.e..E....n|
000000f0 a1 13 da 3c c8 bf 8f 68 6f 67 65 68 6f 67 65 40 |...<...hogehoge@|
00000100 6f 6e 65 2e 6f 63 6e 2e 6e 65 2e 6a 70 00 00 00 |one.ocn.ne.jp...|
00000110 64 00 00 00 06 00 00 00 5c 00 00 00 00 00 00 00 |d.......\.......|
00000120 c8 11 05 00 10 5a d3 55 3c 00 00 00 3c 00 00 00 |.....Z.U<...<...|
00000130 00 16 3e 5a be 76 00 12 e2 70 c9 3e 88 64 11 00 |..>Z.v...p.>.d..|
00000140 47 55 00 06 c2 23 03 01 00 04 00 00 00 00 00 00 |GU...#..........|
00000150 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000160 00 00 00 00 00 00 00 00 00 00 00 00 5c 00 00 00 |............\...|
00000170

書き換え対象の hogehoge は 0xf7 バイトオフセット、つまり 247 バイトを読み進めたところから 8 バイトのデータを書けばよい。

dd で書き換える時は conv=notrunc オプションを設定することが重要となる。

これが付いていないと、書き換えたデータがファイルの末尾となり、以降に存在していたデータは削除されてしまう。( ftruncate(2) )

また、seek=nbytes を設定することで先頭から書き換え対象までの間は変更せずスキップさせる。


ddによる書き換え

$ echo -n "xxxxxxxx" | dd of=pppoe.cap bs=1 seek=247 conv=notrunc

8+0 records in
8+0 records out
8 bytes (8 B) copied, 7.7162e-05 s, 104 kB/s


書き換え後のデータ確認

$ hexdump -C pppoe.cap

00000000 0a 0d 0d 0a 34 00 00 00 4d 3c 2b 1a 01 00 00 00 |....4...M<+.....|
00000010 ff ff ff ff ff ff ff ff 04 00 0e 00 45 64 69 74 |............Edit|
00000020 63 61 70 20 31 2e 31 30 2e 33 00 00 00 00 00 00 |cap 1.10.3......|
00000030 34 00 00 00 01 00 00 00 20 00 00 00 01 00 00 00 |4....... .......|
00000040 ff ff 00 00 09 00 01 00 06 00 00 00 00 00 00 00 |................|
00000050 20 00 00 00 06 00 00 00 5c 00 00 00 00 00 00 00 | .......\.......|
00000060 c8 11 05 00 2e 6f d1 55 3c 00 00 00 3c 00 00 00 |.....o.U<...<...|
00000070 00 16 3e 5a be 76 00 12 e2 70 c9 3e 88 64 11 00 |..>Z.v...p.>.d..|
00000080 47 55 00 1a c2 23 01 01 00 18 10 bc 71 90 18 fe |GU...#......q...|
00000090 6e 3f bd 12 07 89 66 85 68 3b 69 42 41 53 00 00 |n?....f.h;iBAS..|
000000a0 00 00 00 00 00 00 00 00 00 00 00 00 5c 00 00 00 |............\...|
000000b0 06 00 00 00 64 00 00 00 00 00 00 00 c8 11 05 00 |....d...........|
000000c0 1c 70 d1 55 41 00 00 00 41 00 00 00 00 12 e2 70 |.p.UA...A......p|
000000d0 c9 3e 00 16 3e 5a be 76 88 64 11 00 47 55 00 2d |.>..>Z.v.d..GU.-|
000000e0 c2 23 02 01 00 2b 10 65 02 01 45 0e fd dd 19 6e |.#...+.e..E....n|
000000f0 a1 13 da 3c c8 bf 8f 78 78 78 78 78 78 78 78 40 |...<...xxxxxxxx@|
00000100 6f 6e 65 2e 6f 63 6e 2e 6e 65 2e 6a 70 00 00 00 |one.ocn.ne.jp...|
00000110 64 00 00 00 06 00 00 00 5c 00 00 00 00 00 00 00 |d.......\.......|
00000120 c8 11 05 00 10 5a d3 55 3c 00 00 00 3c 00 00 00 |.....Z.U<...<...|
00000130 00 16 3e 5a be 76 00 12 e2 70 c9 3e 88 64 11 00 |..>Z.v...p.>.d..|
00000140 47 55 00 06 c2 23 03 01 00 04 00 00 00 00 00 00 |GU...#..........|
00000150 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000160 00 00 00 00 00 00 00 00 00 00 00 00 5c 00 00 00 |............\...|
00000170

編集後のファイル は Vim の場合も dd の場合も同じ結果になる。


Vim でバイナリ編集

おおまかに言って


  • バイナリモードで開いて


  • :%!xxd を打って

  • 編集して


  • :%!xxd -r を打って

  • 保存終了

すればよい。

まず vi -b pppoe.cap のようにしてバイナリモードでファイルを開く

次に、Vim 上で :%!xxd を実行して hex dump に変換する

(今回くらい簡単なら変換せずに書き換えられるが)

データを変換しただけで Vim なので、通常の操作で

hogehoge に該当する 0x0f0 バイトオフセットの行の 68 6f67 6568 6f67 65 の部分を書き換える。

右側の ASCII 表示はファイルの内容に反映されないのでそのままでよい。

今回は 78 7878 7878 7878 78 (xxxxxxxx) に書き換える。

このまま保存するとテキストファイルになってしまうので、:%!xxd -r でバイナリに戻して保存する

編集後のファイル は Vim の場合も dd の場合も同じ結果になる。


編集後のファイル