id:n7shi:20100205に引き続いてa.outを分析します。アセンブリ版ではサイズ縮小のためセクションを削りましたが、セクションを確認するためC言語版を分析します。
int m[] = { 0, 1/*EXIT*/, 42, 0, 0, 0, 0, 0, 0 }; void start() { asm("mov eax, 0; mov ecx, 3; int 0x21" :: "b"(m)); }
配列をローカルで定義するとスタックへコピーされて冗長になるため、関数の外に出しました。
セクションの配置
自作ツールで分析します。
% aout-tool a.out 00000000: a_magic 01 03 magic number a.out executable 00000002: a_flags 04 flags, see below A_NSYM 00000003: a_cpu 10 cpu id A_I80386: A_BLR=0, A_WLR=0 00000004: a_hdrlen 30 length of header A_HASRELS A_HASEXT 00000005: a_unused 00 reserved for future use 00000006: a_version 0000 version stamp (not used at present) 00000008: a_text 00000018 size of text segement in bytes 0000000c: a_data 00000040 size of data segment in bytes 00000010: a_bss 00000000 size of bss segment in bytes 00000014: a_entry 00000000 entry point 00000018: a_total 00500058 total memory allocated 0000001c: a_syms 00000000 size of symbol table 00000020: a_trsize 00000000 text relocation size 00000024: a_drsize 00000000 data relocation size 00000028: a_tbase 00000000 text relocation base 0000002c: a_dbase 00000000 data relocation base A_TEXTPOS: 00000030 <- a_hdrlen A_DATAPOS: 00000048 <- A_TEXTPOS + a_text A_TRELPOS: 00000088 <- A_DATAPOS + a_data A_DRELPOS: 00000088 <- A_TRELPOS + a_trsize
このバイナリは以下の構造になっています。
- 00000000〜0000002f: a.outヘッダ
- 00000030〜00000047: textセクション → プロセス展開後: 00000000〜00000017
- 00000048〜00000087: dataセクション → プロセス展開後: 00000018〜00000057
MINIXはセグメントでメモリを管理していますが、プロセス内の各セクションはフラットに配置されます。
逆アセンブル
objdumpで逆アセンブルしてメモリ配置を確認します。
# i386-pc-minix-objdump -M intel -d a.out a.out: file format a.out-i386-minix Disassembly of section .text: 00000000 <.text>: 0: 55 push ebp 1: 89 e5 mov ebp,esp 3: 53 push ebx 4: bb 18 00 00 00 mov ebx,0x18 9: b8 00 00 00 00 mov eax,0x0 e: b9 03 00 00 00 mov ecx,0x3 13: cd 21 int 0x21 15: 5b pop ebx 16: c9 leave 17: c3 ret
AT&T形式には不慣れなためIntel形式で出力しています。
ebxにはmが代入されています。0x18はdataセクションの先頭を指しているため、各セクションがプロセス内でフラットに並べられていることがわかります。