从名称修饰到虚表恢复:C++ 逆向工程核心指南(含 x64/x86 差异与 STL 识别)
C++ 逆向工程是一项极具挑战性但又非常迷人的技术领域。由于 C++ 是一种编译型语言,且具有多态、继承、模板、异常处理等高级特性,逆向 C++ 二进制文件比逆向 C 语言要复杂得多。
以下是一份关于 C++ 逆向的系统性指南,涵盖核心难点、关键工具、分析方法以及实战技巧。
1. 核心难点:C++ 的特性在汇编中的体现
在逆向 C++ 时,你在汇编代码中找不到“类”或“虚函数”这样的关键字,需要靠特征来识别。
A. 名称修饰
编译器会将函数名、类名、参数类型编码成难以阅读的符号名(如 ?MyClass@GetData@@QEAAHXZ)。
- 目的:支持函数重载和命名空间。
- 逆向技巧:使用
undname工具(Visual Studio 自带)或 IDA Pro 的 Demangle 功能(快捷键Ctrl+F5)来还原可读的函数签名。
B. this 指针
在 C++ 中,成员函数并不是独立存在的代码块,它们有一个隐式参数:this。
- 调用约定:
- x86 (32位):
this通常通过ECX寄存器传递(thiscall约定)。 - x64 / ARM:
this作为第一个参数(RCX或X0)传递。
- x86 (32位):
- 识别特征:当你看到函数内部大量通过某个指针(如
[ECX+0x10])访问数据时,这很可能是成员函数。
C. 虚函数与虚表
这是 C++ 多态的核心,也是逆向的突破口。
- 虚表:类中如果有虚函数,对象的起始地址(
this指针指向的位置)会存放一个指向虚表的指针。 - 内存布局:
[this]-> 指向虚表vtablevtable[0]-> 第一个虚函数地址vtable[1]-> 第二个虚函数地址,依此类推。
- 逆向技巧:在 IDA 中,当你看到类似
mov eax, [ecx] ; call [eax+4]的指令,这就是典型的虚函数调用。可以通过分析虚表来恢复类的继承关系。
D. 异常处理
C++ 的 try/catch 和析构函数的自动调用依赖于 SEH 或 DWARF 等结构化异常处理机制。逆向时会看到大量的 __CxxFrameHandler 或 __gxx_personality_v0 调用,以及 FS:[0] (Windows) 的操作,这些通常可以忽略,重点关注函数的核心逻辑。
2. 核心工具链
- IDA Pro:最强大的静态分析工具。建议配合 Hex-Rays 反编译器使用。对于 C++,反编译的伪代码虽然冗长,但比汇编更容易理解对象布局。
- Ghidra:NSA 开源的逆向工具,免费且功能强大,对 C++ 虚函数和类结构的恢复有不错的支持。
- x64dbg / WinDbg:动态调试工具。用于观察
this指针的值、虚表地址和运行时内存布局。 - Class Informer:IDA 插件,专门用于自动化恢复 C++ 类结构、虚表和 RTTI。
- RTTI:如果程序没有关闭 RTTI (Run-Time Type Information),可以利用
.rdata段中的RTTI Complete Object Locator来恢复类的继承树和类名。
3. 逆向流程与策略
第一步:识别编译器与保护
- 查看入口点:Visual Studio 编译的程序通常有
_main或_WinMain,GCC 则有__libc_start_main。 - 检查区段名:
.text(代码)、.rdata(只读数据,存放虚表)、.data(全局对象)。 - 注意:如果程序被 混淆 或 加壳,需要先脱壳。
第二步:定位关键对象与类结构
- 寻找
new/delete:搜索operator new或malloc,回溯调用者,往往能发现对象的创建位置。 - 分析构造函数:
- 构造函数负责设置虚表指针 (
mov [this], offset vtable) 和初始化成员变量。 - 关键:通过构造函数中的
vtable地址,你可以知道该类有哪些虚函数。
- 构造函数负责设置虚表指针 (
- 分析析构函数:
- 析构函数通常会先恢复虚表(防止在继承链中调用错误),然后释放资源。析构函数往往会被放在
__try块中或在对象生命周期结束时调用。
- 析构函数通常会先恢复虚表(防止在继承链中调用错误),然后释放资源。析构函数往往会被放在
第三步:恢复虚表
- 在 IDA 中导航到
.rdata段,找到构造函数里赋值的那个地址。 - 将该地址定义为
array或结构体。列表中的每个指针都是一个虚函数。 - 双击进入这些虚函数,分析其功能。通过虚函数的功能(如
Draw、Update、Serialize)来推断类的用途。
第四步:分析对象内存布局
在 IDA 的伪代码窗口中,你可以看到类似 v1[3] = 0 或 *(_DWORD *)(this + 12) = 5 的代码。
- 技巧:将这些偏移量(0, 4, 8, 12…)定义为结构体(Local Types)。
+0: 通常是指向虚表的指针。+4,+8: 通常是成员变量。
- 通过观察函数对这些偏移量的读写,你可以反向还原出类的成员变量类型。
4. 不同编译器的特征
MSVC (Windows)
- 调用约定:
thiscall(ECX传this)。 - 名称修饰:以
?开头,包含@和@@。 - 虚表结构:包含
RTTI Complete Object Locator指针在前(如果开启RTTI),然后是虚函数地址。 - 栈帧:通常有
push ebp; mov ebp, esp的标准帧,且有安全检查__security_check_cookie。
GCC/MinGW (Linux/Unix-like)
- 调用约定:
System V AMD64(this 是第一个参数,即 RDI)。 - 名称修饰:以
_Z开头(如_ZN7MyClass3getEv),使用c++filt工具解码。 - 虚表:通常放在
.rodata段。 - 特点:GCC 生成的代码优化程度通常较高,函数体较短,内联较多。
5. 高级对抗与技巧
- RTTI 恢复类名:如果你在 IDA 中看到
const type_info结构,里面可能包含了类名。利用这一点,你可以直接获取开发者的原始类名,这对理解程序逻辑帮助极大。 - 识别 STL:C++ 标准库(如
std::string,std::vector,std::map)在汇编中非常庞大。- std::string:通常占用 24 或 32 字节,内部包含一个指向堆内存的指针、长度和容量。如果字符串长度小于特定阈值(如 16 字节),会存储在栈上的
buffer数组里(SSO)。 - std::vector:包含
start,finish,end_of_storage三个指针。通过分析push_back的调用逻辑(检查容量,必要时调用reallocate),可以快速识别。
- std::string:通常占用 24 或 32 字节,内部包含一个指向堆内存的指针、长度和容量。如果字符串长度小于特定阈值(如 16 字节),会存储在栈上的
- 模板:模板在编译时生成具体代码。逆向时你会看到大量功能相似但类型不同的函数(如
vector<int>::push_back和vector<string>::push_back)。通常需要手动比对差异来理解具体类型。
6. 学习建议
- 先写后逆:自己用 C++ 写一段代码(包含继承、虚函数、STL),编译成 Release 版本,然后用 IDA 打开。对比源码和汇编/反编译结果,这是最快的学习方式。
- 关注数据流:C++ 逆向容易陷入“这个虚函数是什么”的困境。建议先关注数据的来源(输入)和去向(输出),先不管具体类的名字,先理解数据的流向和变换。
- 动态调试:静态分析很难确定虚函数表的具体内容(尤其是涉及多继承时)。使用调试器在创建对象后下断点,直接查看
this指针指向的内存(即虚表地址),然后跳转到虚表地址查看函数列表。
如果你有具体的二进制文件、报错信息,或者在进行逆向时遇到了特定类型的阻碍(例如遇到了复杂的虚函数表,或者难以理解的反编译器伪代码),可以告诉我更具体的情况,我们可以进一步分析。
学习资源
如果你也是零基础想转行网络安全,却苦于没系统学习路径、不懂核心攻防技能?光靠盲目摸索不仅浪费时间,还消磨自己信心。这份 360 智榜样学习中心独家出版《网络攻防知识库》专为转行党量身打造!
01 内容涵盖
这份资料专门为零基础转行设计,19 大核心模块从 Linux系统、Python 基础、HTTP协议等地基知识到 Web 渗透、代码审计、CTF 实战层层递进,攻防结合的讲解方式让新手轻松上手,真实实战案例 + 落地脚本直接对标企业岗位需求,帮你快速搭建转行核心技能体系!


这份完整版的网络安全学习资料已经上传CSDN【保证100%免费】

02 知识库价值
- 深度: 本知识库超越常规工具手册,深入剖析攻击技术的底层原理与高级防御策略,并对业内挑战巨大的APT攻击链分析、隐蔽信道建立等,提供了独到的技术视角和实战验证过的对抗方案。
- 广度: 面向企业安全建设的核心场景(渗透测试、红蓝对抗、威胁狩猎、应急响应、安全运营),本知识库覆盖了从攻击发起、路径突破、权限维持、横向移动到防御检测、响应处置、溯源反制的全生命周期关键节点,是应对复杂攻防挑战的实用指南。
- 实战性: 知识库内容源于真实攻防对抗和大型演练实践,通过详尽的攻击复现案例、防御配置实例、自动化脚本代码来传递核心思路与落地方法。
03 谁需要掌握本知识库
- 负责企业整体安全策略与建设的 CISO/安全总监
- 从事渗透测试、红队行动的 安全研究员/渗透测试工程师
- 负责安全监控、威胁分析、应急响应的 蓝队工程师/SOC分析师
- 设计开发安全产品、自动化工具的 安全开发工程师
- 对网络攻防技术有浓厚兴趣的 高校信息安全专业师生
04 部分核心内容展示

360智榜样学习中心独家《网络攻防知识库》采用由浅入深、攻防结合的讲述方式,既夯实基础技能,更深入高阶对抗技术。
内容组织紧密结合攻防场景,辅以大量真实环境复现案例、自动化工具脚本及配置解析。通过策略讲解、原理剖析、实战演示相结合,是你学习过程中好帮手。
1、网络安全意识

2、Linux操作系统

3、WEB架构基础与HTTP协议

4、Web渗透测试

5、渗透测试案例分享

6、渗透测试实战技巧

7、攻防对战实战

8、CTF之MISC实战讲解

这份完整版的网络安全学习资料已经上传CSDN【保证100%免费】

更多推荐

所有评论(0)