小聊 .dynstr 節區

jollen 發表於 March 5, 2007 12:31 PM

昨天與同學小談了一下 .dynstr 節區,簡單紀錄如下。

我們知道 ld.so(dynamic linker/loader)與 ldd 指令,而這二個程式都會參考到 ELF 的 .dynstr(dynamic linking 的 string table)。以 ldd 來說,我們用 ldd 來找出 ELF 執行檔的相依動態程式庫:

# ldd hello
        libc.so.6 => /lib/tls/libc.so.6 (0x42000000)
        /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)

這個動作依賴 .dynstr 節區所提供的資訊,也就是說,當 .dynstr 的內容有誤或是不存在時,ld.so ldd 便無法正常工作。例如:

# strip -R .dynstr hello
# ldd hello
./hello: ./hello: no version information available (required by ./hello)
# ./hello
./hello: ./hello: no version information available (required by ./hello)
./hello: relocation error: ./hello: symbol , version  not defined in file  with link time reference

另外再補充一點,在 .dynamic 節區裡的列表中,包含了一筆指向 .dynstr 節區的紀錄。使用簡單的工具操作此觀念如下:

# readelf  -S hello
...
Section Headers:
  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            00000000 000000 000000 00      0   0  0
  [ 1] .interp           PROGBITS        080480f4 0000f4 000013 00   A  0   0  1
  [ 2] .note.ABI-tag     NOTE            08048108 000108 000020 00   A  0   0  4
  [ 3] .hash             HASH            08048128 000128 000028 04   A  4   0  4
  [ 4] .dynsym           DYNSYM          08048150 000150 000050 10   A  5   1  4
  [ 5] .dynstr           STRTAB          080481a0 0001a0 00004c 00   A  0   0  1
  [ 6] .gnu.version      VERSYM          080481ec 0001ec 00000a 02   A  4   0  2
...

接著:

# readelf  -d hello

Dynamic segment at offset 0x414 contains 20 entries:
  Tag        Type                         Name/Value
 0x00000001 (NEEDED)                     Shared library: [libc.so.6]
 0x0000000c (INIT)                       0x8048230
 0x0000000d (FINI)                       0x80483d4
 0x00000004 (HASH)                       0x8048128
 0x00000005 (STRTAB)                     0x80481a0
 0x00000006 (SYMTAB)                     0x8048150
 0x0000000a (STRSZ)                      76 (bytes)
 0x0000000b (SYMENT)                     16 (bytes)
 0x00000015 (DEBUG)                      0x0
 0x00000003 (PLTGOT)                     0x80494f0
 0x00000002 (PLTRELSZ)                   16 (bytes)
 0x00000014 (PLTREL)                     REL
 0x00000017 (JMPREL)                     0x8048220
 0x00000011 (REL)                        0x8048218
 0x00000012 (RELSZ)                      8 (bytes)
 0x00000013 (RELENT)                     8 (bytes)
 0x6ffffffe (VERNEED)                    0x80481f8
 0x6fffffff (VERNEEDNUM)                 1
 0x6ffffff0 (VERSYM)                     0x80481ec
 0x00000000 (NULL)                       0x0

這裡的 "dynamic segment" 專指 ".dynamic" section,與上一篇日記提到的 "dynamic segment" 含義不同,特別一提,以避免混淆。

Jollen's Blog 使用 Github issues 與讀者交流討論。請點擊上方的文章專屬 issue,或 open a new issue

您可透過電子郵件 jollen@jollen.org,或是 Linkedin 與我連絡。更歡迎使用微信,請搜尋 WeChat ID:jollentw