本页面描述了 Ghidra 的 C++ 类恢复系统,该系统通过分析二进制文件,利用运行时类型信息 (RTTI) 重构 C++ 类层次结构、继承关系、虚函数表和类成员数据。该系统支持 Visual Studio/Windows 和 GCC 编译的二进制文件,其中对 Windows 二进制文件的支持更为完善。
关于 Ghidra 中的通用面向对象分析,请参见高级分析功能 (#6)。
C++ 类恢复系统分析已编译二进制文件中的 RTTI 结构,以恢复面向对象编程构件。它识别类层次结构、继承关系(包括虚继承)、虚函数表、构造函数、析构函数和类成员数据。恢复的信息将应用于程序,通过正确识别 this 指针、类方法和成员变量访问,使反编译代码更具可读性。
来源:Ghidra/Features/Decompiler/ghidra_scripts/RecoverClassesFromRTTIScript.java302-308 Ghidra/Features/Decompiler/ghidra_scripts/classrecovery/RTTIClassRecoverer.java95-98
使用 Visual Studio(或面向 Windows 的 Clang)编译的 Windows C++ 程序使用一种特定的 RTTI 格式,其中包括
Complete Object Locator 结构,指向类型信息Class Hierarchy Descriptor 结构,描述继承关系Base Class Descriptor 数组,列出父类GCC 编译的二进制文件使用不同的 RTTI 格式,包含
__class_type_info、__si_class_type_info、__vmi_class_type_info)来源:Ghidra/Features/Decompiler/ghidra_scripts/classrecovery/RTTIWindowsClassRecoverer.java44-58 Ghidra/Features/Decompiler/ghidra_scripts/classrecovery/RTTIGccClassRecoverer.java48-61
RecoveredClass 对象表示一个重构的 C++ 类,包含以下信息:
来源:Ghidra/Features/Decompiler/ghidra_scripts/classrecovery/RecoveredClass.java32-197
抽象类 RTTIClassRecoverer 作为基于 RTTI 的类恢复的基类,针对不同的编译器格式有专门的实现:
RTTIWindowsClassRecoverer:处理 Windows/Visual Studio RTTI 格式RTTIGccClassRecoverer:处理 GCC RTTI 格式来源:Ghidra/Features/Decompiler/ghidra_scripts/classrecovery/RTTIClassRecoverer.java34-100 Ghidra/Features/Decompiler/ghidra_scripts/classrecovery/RTTIWindowsClassRecoverer.java39-100
第一步是识别二进制文件中的 RTTI 结构
Complete Object Locator 结构,这些结构指向 Class Hierarchy Descriptor 和 Base Class Array 结构__class_type_info、__si_class_type_info、__vmi_class_type_info)利用 RTTI 信息,系统将:
来源:Ghidra/Features/Decompiler/ghidra_scripts/classrecovery/RTTIWindowsClassRecoverer.java138-141 Ghidra/Features/Decompiler/ghidra_scripts/classrecovery/RTTIGccClassRecoverer.java626-700
系统根据以下信息识别构造函数和析构函数:
来源:Ghidra/Features/Decompiler/ghidra_scripts/classrecovery/RTTIWindowsClassRecoverer.java153-155 Ghidra/Features/Decompiler/ghidra_scripts/RecoverClassesFromRTTIScript.java326-329
最后,系统会:
this 参数来源:Ghidra/Features/Decompiler/ghidra_scripts/classrecovery/RTTIWindowsClassRecoverer.java169-176 Ghidra/Features/Decompiler/ghidra_scripts/classrecovery/RTTIClassRecoverer.java208-248
类恢复的主要脚本是 RecoverClassesFromRTTIScript.java,它提供了几个选项:
| 选项 | 描述 |
|---|---|
| PRINT_CLASS_DEFINITIONS | 将类似 C 语言的类定义打印到控制台 |
| PRINT_CLASS_INFO | 打印类信息(父类、子类、虚函数、成员数据) |
| PRINT_CLASS_HIERARCHIES | 打印每个类的层次结构 |
| FIXUP_PROGRAM | 查找缺失的 RTTI 结构和潜在函数 |
| BOOKMARK_FOUND_FUNCTIONS | 为已识别的构造函数/析构函数创建书签 |
| GRAPH_CLASS_HIERARCHIES | 显示类关系的可视化图表 |
| USE_SHORT_TEMPLATE_NAMES | 在结构字段中使用缩短的模板名称 |
当脚本运行时,它会:
来源:Ghidra/Features/Decompiler/ghidra_scripts/RecoverClassesFromRTTIScript.java94-117 Ghidra/Features/Decompiler/ghidra_scripts/RecoverClassesFromRTTIScript.java164-343
ApplyClassFunctionSignatureUpdatesScript.java 脚本在列表中修改函数签名时,更新数据类型管理器中的类函数定义。
来源:Ghidra/Features/Decompiler/ghidra_scripts/ApplyClassFunctionSignatureUpdatesScript.java40-160
ApplyClassFunctionDefinitionUpdatesScript.java 脚本在数据类型管理器中修改类函数定义时,更新列表中函数签名。
来源:Ghidra/Features/Decompiler/ghidra_scripts/ApplyClassFunctionDefinitionUpdatesScript.java40-119
GraphClassesScript.java 创建类层次结构的可视化图表,显示继承关系
在图中
来源:Ghidra/Features/Base/ghidra_scripts/GraphClassesScript.java114-211
Windows RTTI 使用以下结构:
RTTI_Complete_Object_Locator:指向类型信息和类层次结构RTTI_Class_Hierarchy_Descriptor:包含继承标志和基类数量RTTI_Base_Class_Array:基类描述符指针数组RTTI_Base_Class_Descriptor:关于基类的信息来源:Ghidra/Features/Decompiler/ghidra_scripts/classrecovery/RTTIWindowsClassRecoverer.java44-59
GCC RTTI 使用:
__class_type_info:用于无继承的类__si_class_type_info:用于单一继承的类__vmi_class_type_info:用于多重继承或虚继承的类来源:Ghidra/Features/Decompiler/ghidra_scripts/classrecovery/RTTIGccClassRecoverer.java48-66
来源:Ghidra/Features/Decompiler/ghidra_scripts/RecoverClassesFromRTTIScript.java16-51
来源:Ghidra/Features/Decompiler/ghidra_scripts/RecoverClassesFromRTTIScript.java92-180 Ghidra/Features/Decompiler/ghidra_scripts/classrecovery/RTTIClassRecoverer.java34-95 Ghidra/Features/Decompiler/ghidra_scripts/classrecovery/RecoveredClassHelper.java50-170