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

如何反解析readelf .symtable中的符号名及调用偏移含义?

C++ 修饰名反解析方法

有几种工具链自带的方式可直接完成反解析,不需要手动对照C++名称修饰规则推导:

  • 直接使用GNU binutils自带的c++filt工具,传入修饰后的符号名作为参数即可输出原始C++符号,例如执行c++filt _ZNSirsERi就能直接得到对应的函数原型
  • 反汇编时给objdump添加-C(即--demangle)参数,反汇编输出会自动对所有C++修饰名做反解析,不需要手动逐个转换
  • 使用gdb加载目标文件时默认开启符号反解析,查看反汇编、符号表时都会直接显示可读的原始符号名
列出的三个修饰符号对应含义

通过标准反解析可以得到三个符号的实际定义:

  • _ZSt3cin:即你已知的std::cin,C++标准库的全局标准输入流对象
  • _ZNSirsERi:std::istream::operator>>(int&),是istream类针对int类型重载的输入运算符,也就是代码中写cin >> int类型变量时实际调用的成员函数
  • _ZNSolsEi:std::ostream::operator<<(int),是ostream类针对int类型重载的输出运算符,对应代码中cout << int类型变量的输出操作
调用指令中-0x4偏移的本质

这个偏移不是指调用_ZNSirsERi对应函数前4字节的位置,是未链接目标文件的重定位状态导致的反汇编显示偏差:
你当前持有的是还没经过链接步骤的.o可重定位目标文件,readelf输出里这几个符号都是UND(未定义)类型,说明它们不属于当前编译单元,实际内存地址需要链接阶段才会分配。x86-64架构下对这类外部跨模块函数的调用会走PLT(过程链接表)桩指令中转,未完成重定位时这些PLT桩没有分配最终地址,也没有生成对应的专属符号,反汇编器生成符号标注时,会找距离调用目标地址最近的符号,再计算相对偏移拼到标注里。这里的_ZNSirsERi-0x4就是反汇编器就近匹配到_ZNSirsERi符号后算出偏移为-0x4的显示结果,这条call指令的实际跳转目标就是std::istream::operator>>(int&)对应的PLT桩,不存在偏移4字节调用的逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 10:45:49