個人的なまとめ。

何かてきとーに書きます。

【Unix/Linux】odコマンドでバイナリを読む【備忘録】

od(Octal Dump)コマンドでバイナリを読むため備忘録

内容

odコマンド

http://x68000.q-e-d.net/~68user/unix/pickup?odによるとodコマンドとは次のように説明されている.

UNIX/Linuxにおけるodコマンドはファイルや標準入力のデータを 8進数・10進数・16進数で表示するコマンドである。

使い方は以下を参照してください.

man od

つかってみよう

まず適当なテキストファイルを作る.

echo "a" > tekito.txt

さっそくこのファイルをodコマンドを使って読んでみる.

od -A x -t x1z -v tekito.txt

ここで,コマンド引数の意味は以下の通りです.

  • -A x: 16進数で表示
  • -t x1z: 1バイト(16進数2桁ずつ)表示して,右にはASCII文字を表示(空白やタブ,改行は.で表示される)
  • -v: 出力の省略をさせない

すると以下のような出力が得られる.

000000 61 0a                                            >a.<
000002

この出力からaは16進数の61で表現される.つまり二進数表記では(0110 0001)となり,
改行コードかEOFがどうやら0aっぽいということがわかる.

もうすこし使ってみよう

適当なテキストファイルを作る.

# a(空白)b(空白)cのファイルを作る.
echo "a b c" > tekito.txt

さきほどと同様に,このファイルをodコマンドを使って読んでみる.

od -A x -t x1z -v tekito.txt

すると以下のような出力が得られる

000000 61 20 62 20 63 0a                                >a b c.<
000006

この出力から空白文字は16進数の20で表現される.つまり二進数表記では(0010 0000)となり,
bとcはそれぞれ62と63,つまり(0110 0010)と(0110 0011)で表現されていることがわかる.

C言語ソースコードをodコマンドで見てみよう

まずは以下のようなHello.cを作成する.

#include <stdio.h>

int main(){
	printf("Hello\n");
	return(0);
}


そしてもうお手の物であるodコマンドで確認.

od -A x -t x1z -v Hello.c

すると以下のような出力が得られる.

000000 23 69 6e 63 6c 75 64 65 20 3c 73 74 64 69 6f 2e  >#include <stdio.<
000010 68 3e 0a 0a 69 6e 74 20 6d 61 69 6e 28 29 7b 0a  >h>..int main(){.<
000020 09 70 72 69 6e 74 66 28 22 48 65 6c 6c 6f 5c 6e  >.printf("Hello\n<
000030 22 29 3b 0a 09 72 65 74 75 72 6e 28 30 29 3b 0a  >");..return(0);.<
000040 7d 0a                                            >}.<
000042

この程度の出力でもすでに対応を取るのは難しいので,-aオプションをつけて見やすくする.

od -A x -t x1z -v -a Hello.c

すると以下のような出力が得られる.

000000  23  69  6e  63  6c  75  64  65  20  3c  73  74  64  69  6f  2e  >#include <stdio.<
         #   i   n   c   l   u   d   e  sp   <   s   t   d   i   o   .
000010  68  3e  0a  0a  69  6e  74  20  6d  61  69  6e  28  29  7b  0a  >h>..int main(){.<
         h   >  nl  nl   i   n   t  sp   m   a   i   n   (   )   {  nl
000020  09  70  72  69  6e  74  66  28  22  48  65  6c  6c  6f  5c  6e  >.printf("Hello\n<
        ht   p   r   i   n   t   f   (   "   H   e   l   l   o   \   n
000030  22  29  3b  0a  09  72  65  74  75  72  6e  28  30  29  3b  0a  >");..return(0);.<
         "   )   ;  nl  ht   r   e   t   u   r   n   (   0   )   ;  nl
000040  7d  0a                                                          >}.<
         }  nl
000042

この出力から0aは,EOFではなく,改行を表していることがわかる.

では,次にHello.cをコンパイルしてa.outを作ろう.

gcc Hello.c

そしてこのa.outを見てみよう.

od -A x -t x1z a.out

すると出力が...多すぎるかもしれないが,16進数で読めることがわかる.

あとはファイルにでもリダイレクトして好きなようにいじってもいいし,

  • jオプションや-Nオプションを使って必要な部分だけ見てもいい.

まとめ

文字コードを知ったり,ファイルシステムの中身を見るのに便利なodコマンドの備忘録でした.