池袋バイナリ勉強会に行ってきた
[池袋バイナリ勉強会]
http://w.livedoor.jp/ikebin/
2回目です。
1回目はMono Developを使用してBrainFxckという言語処理系を手動で実現するアプリと
実際にBrainFxckの処理系を書きました。
2回目はPDP-11のバイナリハックを行いました。
まずインタプリタのインストール
$ hg clone https://bitbucket.org/7shi/v6run
$ cd v6run
$ sudo make install
$ curl -LO https://bitbucket.org/7shi/v6run/downloads/v6root-20110412.tar.xz
$ sudo tar xvf v6root-20110412.tar.xz -C /usr/local
インタプリタをインストールしたので、テストでCのプログラムを作成してみます。
main() { printf("hello\n"); }
コンパイル&動作確認
$ v6cc hello.c
$ v6run a.out
hello
a.outがPDP-11のバイナリであることを確認
$ file a.out
a.out: PDP-11 executable
- v オプションで逆アセンブルしながら動作を確認する
$ v6run -v a.out
...
binutilsのインストール
逆アセンブラを使用するためにインストールします。
$ curl -LO ftp://gnu.org/gnu/binutils/binutils-2.22.tar.bz2
$ tar xvf binutils-2.22.tar.bz2
$ mkdir pdp11-aout
$ cd pdp11-aout
$ ../binutils-2.22/configure --target=pdp11-aout
$ make // dual coreの場合は make -j2
$ sudo make install
$ v6strip a.out
$ pdp11-aout-objdump -d a.out
今度はアセンブラのプログラムを作成する
write.s
mov $1, r0
sys write
hello
6mov $0, r0
sys exit.data
hello:
$ v6as write.s
$ v6run a.out
hello
$ v6strip a.out
$ pdp11-aout-objdump -d a.outa.out: ファイル形式 a.out-pdp11
セクション .text の逆アセンブル:
00000000 <.text>:
0: 15c0 0001 mov $1, r0
4: 8904 sys 4
6: 0010 .word 20
8: 0006 rtt
a: 15c0 0000 mov $0, r0
e: 8901 sys 1
つぎにobjdumpと同じように出力するプログラムを作ります。
まず出力された a.out をバイナリエディタで見てみました。
$ xxd a.out
0000000: 0701 1000 0600 0000 0000 0000 0000 0100 ................
0000010: c015 0100 0489 1000 0600 c015 0000 0189 ................
0000020: 6865 6c6c 6f0a hello.
a.outファイルのヘッダは以下のサイトを参考にします。
http://www.iecc.com/linker/linker03.html
int a_magic; // magic number
int a_text; // text segment size
int a_data; // initialized data size
int a_bss; // uninitialized data size
int a_syms; // symbol table size
int a_entry; // entry point
int a_trsize; // text relocation size
int a_drsize; // data relocation size
※バイナリのバイト順はリトルエンディアンです。
ヘッダからここでまず大切なのは a_text と a_data です。
バイナリ情報とa.out headerから、
a_text は "00 10" // "1000"はリトルエンディアンで "0010"
a_data は "00 06" // "0600"はリトルエンディアンで "0006"
になります。
次に同じようにバイナリを逆アセンブルするプログラムを仕様書を見ないで書きました。
なんか面倒くさそうなので今回はGroovyで記述。
とりあえず動くものを作成しました。
その後にアセンブラの解説をしてもらいました。
以下そのときのメモ。
mov $1, r0
sys write
hello
6mov $0, r0
sys exit.data
hello:
はC言語でいうと
write(1, "hello¥n", 6);
exit(0);
になるらしい。
rから始まるのはレジスタ。レジスタはr0〜r7まである。※PDP-11の場合
$1は数字の1という意味。
movは代入。sysはシステムコールを呼び出す。
今回はそんな感じでした。
また次回楽しみにしています。