【ELF形式】.interpセクション
前回は、.shstrtabセクションからセクション名を抽出し、セクションヘッダ一覧に代入しました。
オフセット | 内容 | サイズ | 管理セクション名 |
---|---|---|---|
0x0000114c | セクションヘッダ0 | 28h(40d)バイト | "\0" |
0x00001174 | セクションヘッダ1 | 28h(40d)バイト | ".interp" |
0x0000119c | セクションヘッダ2 | 28h(40d)バイト | ".note.ABI-tag" |
0x000011c4 | セクションヘッダ3 | 28h(40d)バイト | ".note.gnu.build-id" |
0x000011ec | セクションヘッダ4 | 28h(40d)バイト | ".gnu.hash" |
0x00001214 | セクションヘッダ5 | 28h(40d)バイト | ".dynsym" |
0x0000123c | セクションヘッダ6 | 28h(40d)バイト | ".dynstr" |
0x00001264 | セクションヘッダ7 | 28h(40d)バイト | ".gnu.version" |
0x0000128c | セクションヘッダ8 | 28h(40d)バイト | ".gnu.version_r" |
0x000012b4 | セクションヘッダ9 | 28h(40d)バイト | ".rel.dyn" |
0x000012dc | セクションヘッダ10 | 28h(40d)バイト | ".rel.plt" |
0x00001304 | セクションヘッダ11 | 28h(40d)バイト | ".init" |
0x0000132c | セクションヘッダ12 | 28h(40d)バイト | ".plt" |
0x00001354 | セクションヘッダ13 | 28h(40d)バイト | ".text" |
0x0000137c | セクションヘッダ14 | 28h(40d)バイト | ".fini" |
0x000013a4 | セクションヘッダ15 | 28h(40d)バイト | ".rodata" |
0x000013cc | セクションヘッダ16 | 28h(40d)バイト | ".eh_frame_hdr" |
0x000013f4 | セクションヘッダ17 | 28h(40d)バイト | ".eh_frame" |
0x0000141c | セクションヘッダ18 | 28h(40d)バイト | ".init_array" |
0x00001444 | セクションヘッダ19 | 28h(40d)バイト | ".fini_array" |
0x0000146c | セクションヘッダ20 | 28h(40d)バイト | ".jcr" |
0x00001494 | セクションヘッダ21 | 28h(40d)バイト | ".dynamic" |
0x000014bc | セクションヘッダ22 | 28h(40d)バイト | ".got" |
0x000014e4 | セクションヘッダ23 | 28h(40d)バイト | ".got.plt" |
0x0000150c | セクションヘッダ24 | 28h(40d)バイト | ".data" |
0x00001534 | セクションヘッダ25 | 28h(40d)バイト | ".bss" |
0x0000155c | セクションヘッダ26 | 28h(40d)バイト | ".comment" |
0x00001584 | セクションヘッダ27 | 28h(40d)バイト | ".shstrtab" |
0x000015ac | セクションヘッダ28 | 28h(40d)バイト | ".symtab" |
0x000015d4 | セクションヘッダ29 | 28h(40d)バイト | ".strtab" |
ところで、0番目のセクションのセクション名は空文字列ですが、これは何なのでしょうか。
0番目のセクションヘッダの内容をダンプしてみると、
$ od -x -A x -j0x114c -N0x28 sample 00114c 0000 0000 0000 0000 0000 0000 0000 0000 * 00116c 0000 0000 0000 0000 001174
40バイトが、すべて0で埋め尽くされていますね。セクション名の.shstrtabにおける位置情報が0ですが、.shstrtabの先頭は"\0"なので、結局空文字列ということになります。また、セクション位置(16バイト目からの4バイト領域の値)も0x0000であり、これはELFヘッダの先頭を指すことになりますが、セクションのサイズ情報(20バイト目からの4バイト領域の値)も0x0000なので、結局「サイズ無し」となり、まったく意味をなさないセクションヘッダとなります。このセクションヘッダは何のためにあるんだろう??
さておき今回からは、30個あるセクションの内容について見てみたいと思います。
まず、0番目のセクションヘッダは「空のセクション情報」なので、とりあえず無視しておきます。
1番目のセクションヘッダについて見てみます。
$ od -x -A x -j0x1174 -N0x28 sample 001174 001b 0000 0001 0000 0002 0000 8154 0804 001184 0154 0000 0013 0000 0000 0000 0000 0000 001194 0001 0000 0000 0000 00119c
Elf_Shdr | バイナリ | 項目 | バイナリの意味 |
---|---|---|---|
.sh_name | 0x1b | セクション名 | ".interp" |
.sh_type | 0x01 | セクションのタイプ | アプリケーションプログラムの本体領域(SHT_PROGBITS) |
.sh_flags | 0x02 | 各種フラグ | ロード時にメモリ上に領域確保するセクション(SHF_ALLOC) |
.sh_addr | 0x08048154 | ロード先アドレス | - |
.sh_offset | 0x0154 | ELF形式中でのセクションの位置 | - |
.sh_size | 0x0013 | セクションのバイトサイズ | - |
.sh_link | 0x00 | (セクションのタイプ依存で利用) | - |
.sh_info | 0x00 | (同上) | - |
.sh_addralign | 0x01 | セクションがメモリにロードされる際のバイトアラインメント | - |
.sh_entsize | 0x00 | 構造体配列になっているセクションで利用される。配列要素のサイズ | - |
.interpセクションの内容をダンプしてみます。
$ od -x -A x -w16 -j0x154 -N0x13 sample 000154 6c2f 6269 6c2f 2d64 696c 756e 2e78 6f73 000164 322e 0000 000167
バイナリデータのままだとよく分からないので、readelfコマンドで当該セクションをダンプしてみます。
$ readelf -x0 sample セクション '.interp' の 十六進数ダンプ: 0x08048154 2f6c6962 2f6c642d 6c696e75 782e736f /lib/ld-linux.so 0x08048164 2e3200 .2.
おお、ASCIIデータだったのですね。でも、「/lib/ld-linux.so.2」って何でしょうか。
$ file /lib/ld-linux.so.2 /lib/ld-linux.so.2: symbolic link to `i386-linux-gnu/ld-2.17.so' $ file /lib/i386-linux-gnu/ld-2.17.so /lib/i386-linux-gnu/ld-2.17.so: ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), dynamically linked, BuildID[sha1]=0x6121c48261246146c8b05fde9cfc7de3fa0f9148, stripped
/lib/ld-linux.so.2は、/lib/i386-linux-gnu/ld-2.17.soのシンボリックリンクでした。
では、このld-linux.so.2とは何者か?というと、(リンカ・ローダ本によると)実行形式のロードと動的リンクを行うプログラムだそうです。ここは簡易ローダを実装する際に詳しく見ることにして、今は深堀りしないでおきます。
"Understanding ld-linux.so.2"
http://www.cs.virginia.edu/~dww4s/articles/ld_linux.html