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