对于RTTI结构的资料真的屈指可数,类的逆向也一直是一个不好弄的问题.对此我只想贡献我的一份力量. 文中我不会分析类的内存布局,因为有很多资料已经分析的挺好的了(见参考资料). 但是现有我能找到的资料对RTTI结构的表述不完整,或者表述模糊不清,参考Clang的部分源码后, 我在他们的基础上,补充,扩展了一下RTTI的结构信息.但是仍然也有一部分我也不甚清楚,见谅.
首先给出RTTI结构的完整结构图(图中->是表示两个结构有关联关系):
@VfTable包含ClassVfTable,类的虚表指针vfptr指向@VfTable+4的位置,即vfptr=@VfTable+4=ClassVfTable 我是为了统一一下才这样表示的.在类虚表位置-4的地方,也就是ClassVfTable-4.指向CompleteObjectLocator结构. 现在对每一个结构进行简单的解释. CompleteObjectLocator { +0 isImageRelative: DWORD +4 VfOffsetToTop: DWORD +8 VFPtrOffset: DWORD +12 pTypeDescriptor: TypeDescriptor* +16 pClassHierarchyDescriptor: ClassHierarchyDescriptor * [+20 -pSelf: DWORD *] //只在X64时存在,指向自身 } isImageRelative: RTTI结构中的所有指针是否是与映象基地址相关,这是X64与X32的区别. 当是X32时为0,指针含义没有变.但在X64时为1,此时RTTI结构中所有指针不再是指针,而是相对于基地址的偏移量.
VfOffsetToTop: vftable 在类中的偏移
VFPtrOffset: 这个含义比较复杂.他是在有虚基类被继承多次,并且虚基类的(纯)虚函数被多次覆写时存在. 是虚表指针相对与最近的一个虚基类的偏移.
TypeDescriptor { +0 pVFtable: DWORD* //指向虚表 +4 Spare: DWORD //存储运行时数据,静态分析时总是0. +8 pTypeInfoString: char* //指向类名. }
ClassHierarchyDescriptor { +0 Unknown: DWORD = 0 //我没查到它的信息. +4 ClassHierarchyFlags: DWORD +8 NumBaseClass: DWORD //基类数量,包括自己,并且对同一基类多次继承(菱形继承)会重复计算的. +12 pBaseClassDescriptorArray: DWORD** //指向BaseClassDescriptor指针数组 } 说一下ClassHierarchyFlags的含义. 定义枚举如下: enum ClassHierarchyDescriptorFlags{ 00252 HasBranchingHierarchy = 1, 00253 HasVirtualBranchingHierarchy = 2, 00254 HasAmbiguousBases = 4 00255 }; ClassHierarchyFlags是根据类是否是多继承,是否是多虚继承,是否有纯虚基类来对上述 枚举量进行异或组合.例如ClassHierarchyFlags=HasBranchingHierarchy|HasVirtualBranchingHierarchy, 表示的含义已经很清楚了. 还剩最后一个结构了. BaseClassDescriptor { +0 pTypeDescriptor: DWORD TypeDescriptor* +4 NumContainedBaseClass: DWORD //基类数量,包括自己,并且对同一基类多次继承(菱形继承)会重复计算的. +8 OffsetInVBase: DWORD //vftable 在虚基类中的偏移 +12 VBPtrOffset: DWORD //vbtable(包含所有虚基类的vftable的偏移的一个表)的偏移.此处参考后面列出的参考资料[1]. +16 OffsetInVBTable: DWORD //类vftable指针在vbtable中的偏移. +20 BaseClassHierarchyFlags: DWORD +24 pClassHierarchyDescriptor: ClassHierarchyDescriptor* } 对于BaseClassHierarchyFlags定义如下枚举: enum BaseClassDescriptorFlags { IsPrivateOnPath = 1 | 8, IsAmbiguous = 2, IsPrivate = 4, IsVirtual = 16, HasHierarchyDescriptor = 64 }; BaseClassHierarchyFlags是根据自己是否被私有继承,是否是纯虚类,是否对基类私有继承,是否为虚基类,是否 有HierarchyDescriptor结构对上述枚举量进行异或组合.
我是在ms2013上进行验证的.我不敢保证Microsoft的编译器RTTI结构一直都没有变化. 文中还有一些地方解释并不清楚,见谅.要是Microsoft把RTTI结构公开就没这么多事儿了.
参考资料: 1.Reversing C++ - Black Hat: https://www./presentations/bh-dc-07/Sabanal_Yason/Paper/bh-dc-07-Sabanal_Yason-WP.pdf 2.openrce igorsk 写的:http://www./articles/full_view/23 3.>. 4.clang源代码: http://clang./doxygen/MicrosoftRTTI_8cpp_source.html 5.https://msdn.microsoft.com/en-us/library/ms879782.aspx
|