Hatena::ブログ(Diary)

ゆずさん研究所

 | 

2013/10/12

【ELF形式】.interpセクション

| 05:41

前回は、.shstrtabセクションからセクション名を抽出し、セクションヘッダ一覧に代入しました。


オフセット内容サイズ管理セクション名
0x0000114cセクションヘッダ028h(40d)バイト"\0"
0x00001174セクションヘッダ128h(40d)バイト".interp"
0x0000119cセクションヘッダ228h(40d)バイト".note.ABI-tag"
0x000011c4セクションヘッダ328h(40d)バイト".note.gnu.build-id"
0x000011ecセクションヘッダ428h(40d)バイト".gnu.hash"
0x00001214セクションヘッダ528h(40d)バイト".dynsym"
0x0000123cセクションヘッダ628h(40d)バイト".dynstr"
0x00001264セクションヘッダ728h(40d)バイト".gnu.version"
0x0000128cセクションヘッダ828h(40d)バイト".gnu.version_r"
0x000012b4セクションヘッダ928h(40d)バイト".rel.dyn"
0x000012dcセクションヘッダ1028h(40d)バイト".rel.plt"
0x00001304セクションヘッダ1128h(40d)バイト".init"
0x0000132cセクションヘッダ1228h(40d)バイト".plt"
0x00001354セクションヘッダ1328h(40d)バイト".text"
0x0000137cセクションヘッダ1428h(40d)バイト".fini"
0x000013a4セクションヘッダ1528h(40d)バイト".rodata"
0x000013ccセクションヘッダ1628h(40d)バイト".eh_frame_hdr"
0x000013f4セクションヘッダ1728h(40d)バイト".eh_frame"
0x0000141cセクションヘッダ1828h(40d)バイト".init_array"
0x00001444セクションヘッダ1928h(40d)バイト".fini_array"
0x0000146cセクションヘッダ2028h(40d)バイト".jcr"
0x00001494セクションヘッダ2128h(40d)バイト".dynamic"
0x000014bcセクションヘッダ2228h(40d)バイト".got"
0x000014e4セクションヘッダ2328h(40d)バイト".got.plt"
0x0000150cセクションヘッダ2428h(40d)バイト".data"
0x00001534セクションヘッダ2528h(40d)バイト".bss"
0x0000155cセクションヘッダ2628h(40d)バイト".comment"
0x00001584セクションヘッダ2728h(40d)バイト".shstrtab"
0x000015acセクションヘッダ2828h(40d)バイト".symtab"
0x000015d4セクションヘッダ2928h(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_name0x1bセクション名".interp"
.sh_type0x01セクションのタイプアプリケーションプログラムの本体領域(SHT_PROGBITS)
.sh_flags0x02各種フラグロード時にメモリ上に領域確保するセクション(SHF_ALLOC)
.sh_addr0x08048154ロード先アドレス-
.sh_offset0x0154ELF形式中でのセクションの位置-
.sh_size0x0013セクションのバイトサイズ-
.sh_link0x00(セクションのタイプ依存で利用)-
.sh_info0x00(同上)-
.sh_addralign0x01セクションがメモリにロードされる際のバイトアラインメント-
.sh_entsize0x00構造体配列になっているセクションで利用される。配列要素のサイズ-

.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

 |