【问题标题】:Why readelf add "@GLIBC_2.2.5 (2)" after FUNC symbols' names in .dynsym symbol table为什么 readelf 在 .dynsym 符号表中的 FUNC 符号名称后添加“@GLIBC_2.2.5 (2)”
【发布时间】:2020-01-15 10:17:50
【问题描述】:

我正在学习 ELF 文件,并以 x86_64 CentOS 7 上的 GCC 构建的 C HelloWorld 程序为例来研究可执行文件。

我可以理解如何为可执行文件中的每个符号找到符号名称,除了动态符号表 (.dynsym) 中的两个符号。

以符号表(.symtab)中的“main”符号为例:

$ readelf -s HelloWorld
...
Symbol table '.symtab' contains 84 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
...
    80: 0000000000400586    21 FUNC    GLOBAL DEFAULT   13 main
...

它的原值为:

                                   Name of this symbol
                                   ^^ ^^ ^^ ^^
00001e20  00 00 00 00 00 00 00 00  fb 03 00 00 12 00 0d 00  |................|
00001e30  86 05 40 00 00 00 00 00  15 00 00 00 00 00 00 00  |..@.............|

值为0x0000 03fb(小edian)。它实际上是 .strtab 节中的一个偏移量,内容如下:

$ readelf -p .strtab HelloWorld

String dump of section '.strtab':
...
  [   3fb]  main
...

所以很容易理解,这个符号的名字是“main”。 .symtab 或 .dynsym 中的每个符号都遵循此规则,但 .dynsym 中的两个符号除外。两个例外是:

$ readelf -s HelloWorld

Symbol table '.dynsym' contains 6 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
...
     2: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND puts@GLIBC_2.2.5 (2)
     3: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND __libc_start_main@GLIBC_2.2.5 (2)
...

以符号#2为例,其原始值为:

                                   Name of the symbol
                                   ^^ ^^ ^^ ^^
000002e0  00 00 00 00 00 00 00 00  0b 00 00 00 12 00 00 00  |................|
000002f0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|

符号名称的偏移量 0x0000 000b。通过查看 .dynstr:

$ readelf -p .dynstr HelloWorld

String dump of section '.dynstr':
  [     1]  libc.so.6
  [     b]  puts
  [    10]  __libc_start_main
  [    22]  GLIBC_2.2.5
  [    2e]  _ITM_deregisterTMCloneTable
  [    4a]  __gmon_start__
  [    59]  _ITM_registerTMCloneTable

我可以看到偏移量 0xb 处的字符串是“puts”。但是为什么readelf会附加一个字符“@”呢?为什么还要附加字符串“GLIBC_2.2.5”(偏移量 0x22)?

【问题讨论】:

    标签: gcc linker elf


    【解决方案1】:

    但是为什么readelf会附加一个字符“@”呢?为什么还要附加字符串“GLIBC_2.2.5”(偏移量 0x22)?

    这些是 GNU 版本的符号。 readelf 附加该信息以使其清楚,否则您将看到例如这个:

      1232: 00000000000792d0   471 FUNC    GLOBAL DEFAULT   13 fmemopen
      1233: 0000000000078ed0   527 FUNC    GLOBAL DEFAULT   13 fmemopen
    

    并且会困惑于如何在不同的地址有两个独立的fmemopens。

    当前输出:

      1232: 00000000000792d0   471 FUNC    GLOBAL DEFAULT   13 fmemopen@GLIBC_2.2.5
      1233: 0000000000078ed0   527 FUNC    GLOBAL DEFAULT   13 fmemopen@@GLIBC_2.22
    

    表明这些符号附加了不同的版本信息,GLIBC_2.22 版本是默认版本。

    您可以阅读更多关于 GNU 版本符号here

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-03-05
      • 2021-07-05
      • 2019-02-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-19
      • 1970-01-01
      相关资源
      最近更新 更多