[Linux] バイナリファイルを表示する - od

今回はコマンドラインでバイナリファイルを閲覧する方法です。サンプルとしてこのブログのアイコン画像を利用しています。

odコマンド

odは引数でファイルのパスを渡すか、標準入力経由で情報を渡すと、バイナリ情報を良い感じに表示してくれるコマンドです。

オプションなし

引数なしで実行するとこんな感じ。デフォルトでは8進数でダンプされます。

$ od icon.png 
0000000 050211 043516 005015 005032 000000 006400 044111 051104
0000020 000000 020000 000000 017400 001410 000000 130400 037610
0000040 000276 000000 050377 052114 043505 046160 104377 177605
0000060 102610 104377 177605 102610 104377 177605 102610 104377
0000100 177605 102610 104377 177605 102610 104377 177605 102610
(中略)
0001560 151124 035457 000000 000000 042511 042116 041256 101140
0001600

一番左側の列はデータではなく、ファイル中の場所(アドレス)です。

8進数,10進数, 16進数で表示

-toで8進数、-tdで10進数、-txで16進数で表示してくれます。

$ od -tx icon.png 
0000000 474e5089 0a1a0a0d 0d000000 52444849
0000020 20000000 1f000000 00000308 3f88b100
0000040 000000be 544c50ff 4c704745 ff8588ff
()

$ od -to icon.png 
0000000 10723450211 01206405015 01500000000 12221044111
0000020 04000000000 03700000000 00000001410 07742130400
0000040 00000000276 12423050377 11434043505 37741304377
()

上記だとちょっと見づらいという場合には、-txないし-toのあとに数字を付けてやると区切り方を変更することができます。数字を付けない場合は-tx4がデフォルトなのがわかりますね。

$ od -tx1 icon.png 
0000000 89 50 4e 47 0d 0a 1a 0a 00 00 00 0d 49 48 44 52
0000020 00 00 00 20 00 00 00 1f 08 03 00 00 00 b1 88 3f
0000040 be 00 00 00 ff 50 4c 54 45 47 70 4c ff 88 85 ff

$ od -tx2 icon.png 
0000000 5089 474e 0a0d 0a1a 0000 0d00 4849 5244
0000020 0000 2000 0000 1f00 0308 0000 b100 3f88
0000040 00be 0000 50ff 544c 4745 4c70 88ff ff85

$ od -tx4 icon.png 
0000000 474e5089 0a1a0a0d 0d000000 52444849
0000020 20000000 1f000000 00000308 3f88b100
0000040 000000be 544c50ff 4c704745 ff8588ff

ASCIIで表示

-tcまたは-taオプションでASCIIコード表に該当する物を、その文字で表示してくれます。冒頭にP N Gの文字があるのがわかりますね。

$ od -tc icon.png
0000000 211   P   N   G  \r  \n 032  \n  \0  \0  \0  \r   I   H   D   R
0000020  \0  \0  \0      \0  \0  \0 037  \b 003  \0  \0  \0 261 210   ?
0000040 276  \0  \0  \0 377   P   L   T   E   G   p   L 377 210 205 377
0000060 210 205 377 210 205 377 210 205 377 210 205 377 210 205 377 210
0000100 205 377 210 205 377 210 205 377 210 205 377 210 205 377 210 205
0000120 377 210 205 377 210 205 377 210 205 377 210 205 377 210 205 377

例えば画像に埋め込まれたコメント(テキスト)情報を探したり、テキストかバイナリか不明のファイルをod経由でとりあえず表示してみると言った用途に利用できます。

また-ta-tcでは以下のように表示方式が異なります。-tcの方がプログラマには馴染みのある表示方法でしょうか。

-ta -tc 意味
sp スペース
nul \0 Null, 0バイト
nl \n 改行
cr \r 復帰

指定バイト数だけ表示する

取り出すバイト数を指定

-Nオプションを付けると指定したバイト数だけ取り出すことができます。以下の例だと冒頭から100byte分だけ取り出しています。

$ od -N 100 icon.png 
0000000 050211 043516 005015 005032 000000 006400 044111 051104
0000020 000000 020000 000000 017400 001410 000000 130400 037610
0000040 000276 000000 050377 052114 043505 046160 104377 177605
0000060 102610 104377 177605 102610 104377 177605 102610 104377
0000100 177605 102610 104377 177605 102610 104377 177605 102610
0000120 104377 177605 102610 104377 177605 102610 104377 177605
0000140 102610 104377
0000144

先頭をスキップ

-jオプションを付けると先頭から指定バイト数分をスキップすることができます。以下の例だと冒頭の300byteをスキップしています。

$ od -j 300 icon.png 
0000454 000000 052000 051164 051516 176000 001772 175776 000775
0000474 002002 012005 173232 167307 062640 005616 060316 003415
0000514 004770 174533 022700 165746 124737 016416 077460 042733
0000534 113161 015143 016027 130657 052611 005077 150734 145674
()

-Nと-jを同時に使う

取り出すバイト数を指定できる-Nと、先頭からスキップする-jを同時に指定することも可能です。以下の例では冒頭300byteの地点から100byteを取り出しています。

$ od -j 300 -N 100 icon.png 
0000454 000000 052000 051164 051516 176000 001772 175776 000775
0000474 002002 012005 173232 167307 062640 005616 060316 003415
0000514 004770 174533 022700 165746 124737 016416 077460 042733
0000534 113161 015143 016027 130657 052611 005077 150734 145674
0000554 041504 114221 122614 146067 003332 156736 043031 053111
0000574 165242 056523 055063 101765 073202 004165 134656 116111
0000614 000000 156001
0000620

接頭辞

バイト数を指定する際、例えば100Mbyteを指定したいとなった場合に、od -j 100000000と書くのはさすがに面倒なため、接頭辞を利用することができます。

キーワード バイト数
b 512
KB 1000
K 1024
MB 1000 * 1000
M 1024*1024

manによるとbはtypoではなく小文字のbです。これ以降も同様にG, T, P, E, Z, Yまで用意されているようです。

改行位置を調整する

デフォルトだと15byte置きに改行されますが、-wオプションで任意のbyte数に変更できます。

$ od icon.png
0000000 050211 043516 005015 005032 000000 006400 044111 051104
0000020 000000 020000 000000 017400 001410 000000 130400 037610
0000040 000276 000000 050377 052114 043505 046160 104377 177605

$ od -w8 icon.png
0000000 050211 043516 005015 005032
0000010 000000 006400 044111 051104
0000020 000000 020000 000000 017400

$ od -w32 icon.png
0000000 050211 043516 005015 005032 000000 006400 044111 051104 000000 020000 000000 017400 001410 000000 130400 037610
0000040 000276 000000 050377 052114 043505 046160 104377 177605 102610 104377 177605 102610 104377 177605 102610 104377
0000100 177605 102610 104377 177605 102610 104377 177605 102610 104377 177605 102610 104377 177605 102610 104377 177605

省略しない

odコマンドは全く同じデータの行が続く場合、自動的にアスタリスク(*)に省略する機能がONになっています。以下の例では実際のデータは5行分ですが、odコマンドでは最初の1行だけが表示され残りは*にまとめられています。

$ cat log.txt
Yeaaaaaaaaaaaa!
Yeaaaaaaaaaaaa!
Yeaaaaaaaaaaaa!
Yeaaaaaaaaaaaa!
Yeaaaaaaaaaaaa!

$ od -tx1 log.txt
0000000 59 65 61 61 61 61 61 61 61 61 61 61 61 61 21 0a
*
0000120

これで問題がある場合には-vオプションをつけることで省略する機能をOFFにできます。

$ od -tx1 -v log.txt
0000000 59 65 61 61 61 61 61 61 61 61 61 61 61 61 21 0a
0000020 59 65 61 61 61 61 61 61 61 61 61 61 61 61 21 0a
0000040 59 65 61 61 61 61 61 61 61 61 61 61 61 61 21 0a
0000060 59 65 61 61 61 61 61 61 61 61 61 61 61 61 21 0a
0000100 59 65 61 61 61 61 61 61 61 61 61 61 61 61 21 0a
0000120

今度は省略されずに表示されました。例えば行末までずっとNULLや改行しか無いといった場合には便利なのですけどね。

アドレスの表示形式を変更する

-Aオプションで左側に表示されているファイル中での位置(アドレス)を、8,10,16進数のいずれかに変更することができます。

$ od -Ax icon.png 
(中略)
000190 042111 052101 147450 051615 071327 030334 056014 026122
0001a0 153552 156575 173675 075736 104757 002235 177777 000455
0001b0 131165 171116 020745 146430 154210 110535 010130 177002
0001c0 176073 130040 112603 001015 017777 061674 156022 064667
0001d0 106772 057637 056536 071407 165426 145653 157763 037025
0001e0 144026 062520 137027 156617 027412 105027 007412 062113
0001f0 122244 003375 154320 024447 026415 034061 000214 022053
000200 032211 000235 176047 062342 140605 020274 130166 043640

上記は16進数の例になります。その他の指定方法は以下の通り。

  • -Axで16進数
  • -Aoで8進数
  • -Adで10進数

アドレスを表示しない

-Anでアドレスを非表示にできます。

$ od -An icon.png 
 050211 043516 005015 005032 000000 006400 044111 051104
 000000 020000 000000 017400 001410 000000 130400 037610
 000276 000000 050377 052114 043505 046160 104377 177605
 102610 104377 177605 102610 104377 177605 102610 104377

利用例

差分を調べる

2つのバイナリファイルの差分を調べたい場合、diffコマンドと組み合わせることで表示することが可能です。

$ diff <(od hello.c) <(od hello2.c)
2,6c2,6
< 0000020 067551 064056 006476 006412 064412 072156 066440 064541
< 0000040 024156 075451 005015 070011 064562 072156 024146 044042
< 0000060 066145 067554 067527 066162 056144 021156 035451 005015
< 0000100 071011 072145 071165 024156 024460 006473 076412 005015
< 0000120
---
> 0000020 067551 064056 005076 064412 072156 066440 064541 024156
> 0000040 075451 004412 071160 067151 063164 021050 062510 066154
> 0000060 053557 071157 062154 067134 024442 005073 071011 072145
> 0000100 071165 024156 024460 005073 005175
> 0000112

以下のサイトを参考にさせていただきました。 zashikiro.hateblo.jp

画像形式を見分ける

例えばGIF, JPEG, PNGなどの画像ファイルは、ファイルの先頭部分を確認することでどの形式か思いの外手軽に見分けることができます。

$ od -tc icon.png
0000000 211   P   N   G  \r  \n 032  \n  \0  \0  \0  \r   I   H   D   R

$ od -tc icon.gif
0000000   G   I   F   8   7   a      \0 037  \0 263  \0  \0  \0  \0  \0

$ od -tx1 icon.jpg
0000000 ff d8 ff e0 00 10 4a 46 49 46 00 01 01 00 00 48

PNGやGIFは冒頭にアスキーで埋め込まれているのがわかりますね。JPEGの場合はファイルの先頭がFFD8かどうかで判定できます。

UnicodeのBOMを発見する

「ファイルの冒頭に変な物が表示される!?」と思ったらBOMが付いていることを疑う場合があります。BOMとはそのファイルの文字コードがUnicodeであることをアプリケーションに教えるためにファイルの先頭につけるバイナリです。BOMがないとUnicodeであることがわからないアプリがある反面、これが原因で誤作動を起こす場合もあります。

もしBOMが付いているか簡単に確認したくなった場合、テキストファイルをodでバイナリとして開きBOMが付いているか確認することができます。

$ od -tx1 hello.c 
0000000 ef bb bf 23 69 6e 63 6c 75 64 65 20 3c 73 74 64
0000020 69 6f 2e 68 3e 0a 0a 69 6e 74 20 6d 61 69 6e 28
0000040 29 7b 0a 09 70 72 69 6e 74 66 28 22 48 65 6c 6c
0000060 6f 57 6f 72 6c 64 5c 6e 22 29 3b 0a 09 72 65 74
0000100 75 72 6e 28 30 29 3b 0a 7d 0a
0000112

UTF-8の場合は冒頭の0xEF 0xBB 0xBFがBOMにあたります。

BOMについて詳しく知りたい場合はWikipediaか、UnicodeのサイトにあるFAQなどを参照してください。

改行コードを確認する

アスキーで表示すると制御コードも文字で表示してくれるため、確認をスムーズに行うことができます。

$ od -tc hello.c 
0000000 357 273 277   #   i   n   c   l   u   d   e       <   s   t   d
0000020   i   o   .   h   >  \r  \n  \r  \n   i   n   t       m   a   i
0000040   n   (   )   {  \r  \n  \t   p   r   i   n   t   f   (   "   H
0000060   e   l   l   o   W   o   r   l   d   \   n   "   )   ;  \r  \n
0000100  \t   r   e   t   u   r   n   (   0   )   ;  \r  \n   }  \r  \n
0000120

ここでは\r \nが定期的に現れているため、Windowsで利用されているCR+LFの可能性が高いなと推測することができます。

参考ページ

Linux コマンド