You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C实现ELF解析时如何识别GOT条目对应函数及.rela.plt符号名

ELF .rela.plt 重定位条目与符号名关联实现方法

核心关联字段你之前漏看了:Elf64_Rela(注意.rela.plt是带加数的重定位表,用的是Elf64_Rela不是Elf64_Rel)结构体的r_info字段本身就编码了符号索引,不需要找其他字段关联。

x86_64架构下ELF标准定义了两个宏拆分r_info:

// 从r_info中提取对应符号在关联符号表中的下标
#define ELF64_R_SYM(info)    ((info) >> 32)
// 从r_info中提取重定位类型
#define ELF64_R_TYPE(info)   ((info) & 0xffffffffULL)

拿你贴的readelf输出直接验证:

  • 第一条重定位项Info值为0x0000000100000007,用ELF64_R_SYM计算得到符号索引为1,正好对应.dynsym表中下标为1的条目,就是free@GLIBC_2.2.5
  • 第二条重定位项Info值为0x0000000500000007,计算得到符号索引为5,对应.dynsym下标5的malloc@GLIBC_2.2.5,和readelf输出的符号名完全一致。

.rela.plt段关联的符号表固定是.dynsym,关联的字符串表固定是.dynstr,不需要额外判断关联关系。

为什么st_shndx为SHN_UNDEF是正常现象

你之前猜测的st_shndx字段不参与这个关联逻辑。malloc、free是从glibc动态导入的符号,本身不存在于当前可执行文件的任何段中,所以符号表项的段索引必然是SHN_UNDEF,这个值只用来标记符号是导入还是本地定义,和重定位关联无关。

GOT条目与函数匹配的完整步骤

  • 加载解析ELF头,找到.rela.plt、.dynsym、.dynstr、.got.plt(即存储函数地址的GOT段)的加载基地址和长度
  • 遍历.rela.plt中每一个Elf64_Rela条目
  • 对每个条目,用ELF64_R_SYM(r_info)取出符号索引,用这个索引直接索引.dynsym数组得到对应的Elf64_Sym结构
  • 用Elf64_Sym结构的st_name字段作为偏移,加上.dynstr基地址,就能拿到对应的符号名字符串(这步你已经实现)
  • 重定位条目的r_offset字段就是GOT表中对应条目的虚拟地址(文件映射状态下是文件内偏移),把这个地址和拿到的符号名绑定,就完成了GOT条目到对应函数的匹配。

注意:32位ELF的r_info拆分规则不同,ELF32_R_SYM是取info >> 8,如果需要兼容32位程序要单独做逻辑判断,不要直接套用64位的移位规则。

内容的提问来源于stack exchange,提问作者Daniel Walker

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 04:18:17