IDA无法显示C++函数名是因编译器剥离符号,调试版(-g)未strip时可识别;Release版需人工分析控制流、字符串等;Ghidra需手动Auto-Demangle且注意Demangler设置;vtable地址不匹配需检查PIE、重定位及ABI细节。

IDA Pro 打开 C++ 程序后看不到函数名?
因为编译器默认剥离符号,C++ 目标文件(.o)或可执行文件没保留 _Z* 编码的函数名,IDA 默认不恢复。不是 IDA 坏了,是它没“原料”。
- 调试版本(
-g编译)+ 未 strip 的 ELF/PE 文件,IDA 能直接识别main、std::vector::push_back这类符号 - Release 版本通常带
-O2 -s,函数名全丢,只剩sub_401230这种占位符;此时得靠控制流、字符串、vtable 偏移等线索人工识别 - 如果用了
-fvisibility=hidden或 LTO,连全局符号都可能被合并,Ghidra 的符号恢复能力比 IDA Free 版稍强,但一样受限于输入文件信息量
Ghidra 导入 C++ 可执行文件后,Demangle 不生效?
Ghidra 默认不会自动 demangle C++ 符号——它得你手动触发,而且只对已识别为 mangled 的名字起作用(比如以 _Z 开头的)。
- 导入时勾选
Analyze after import,但别依赖它自动搞定:分析完右键 Symbol Tree →Auto-Demangle,或选中某条_ZSt6...名称 → 右键 →Demangle - 若显示
Demangle failed,大概率是符号已被 strip,或 Ghidra 没识别出这是 mangled name(常见于 Windows MSVC 编译的??$...格式),可尝试切换 Demangler:Edit → Tool Options → Listing Fields → Demangler → Set to "Microsoft" - 注意:demangle 结果只是推测,
std::basic_string<char ...></char>这类模板实例化名可能仍不完整,得结合上下文判断实际类型
逆向 C++ 虚函数调用,为什么 vtable 地址对不上?
C++ 虚表地址在二进制里是硬编码的指针值,但链接时可能被重定位、PIE 启用后基址随机,或者编译器做了 vtable 合并优化。
- 先确认是否 PIE:
file ./a.out输出含PIE,那 IDA/Ghidra 加载时必须设对基址(Ghidra:Import → Load Image Base = 0x100000000;IDA:Manual Load → Image Base 填运行时地址) - vtable 条目不一定是纯函数指针:GCC 可能插
offset_to_top(负数偏移),MSVC 可能放 RTTI 指针,看到非代码地址别急着标红 - 虚函数调用常见模式:
mov rax, [rdi](取 vtable)→call [rax + 0x10](调第二个虚函数),这时得去 vtable 所在段找对应偏移处的指针,再跳转过去看是不是目标函数
想从反汇编还原 C++ 类结构,光看 mov 和 lea 不够
成员变量偏移、继承关系、虚基类布局这些信息,源码里由编译器决定,反汇编里只留下“结果”,没有注释说明。
立即学习“C++免费学习笔记(深入)”;
- 优先找构造函数:它通常按内存布局顺序给
this+0、this+8等位置赋值,能直接推出字段类型和偏移(例如mov dword ptr [rdi+4], 0→ 第二个 int 成员初始化为 0) - 虚继承会引入额外指针(vbptr),表现为构造函数里多写一个
mov [rdi+X], offset vbtable,这个 X 就是 vbptr 偏移,得单独记下来 - Ghidra 的
Data Type Manager可手动建struct并 apply 到this指针上,但一旦遇到多重继承或模板特化,字段对齐、padding 都得对照 ABI 文档(如 Itanium C++ ABI)核对,不然 struct size 一错,后面全偏
虚函数表偏移、this 指针调整、异常处理帧(.eh_frame)这些细节,不查 ABI 文档或不对比多个编译器输出,很容易按直觉猜错。实际逆向时,有源码片段对照最省力,没源码就得多看几个相似函数交叉验证。



















