三. 术语说明
对于以下将频繁用到的术语,我可能简写为如下
classX:RTTI_COL x 原语:classX:RTTI Complete Object Locator {for x}
classX:RTTI_CHD 原语:classX:RTTI class Hierarchy Descriptor
classX:RTTI_BCD 原语:classX:RTTI Base class Descriptor
以上简写均采用单词首字母缩写,其中Derive表示派生类,x表示Derive的一个基类,classX表示以上任意类
四. 分析
1. 派生类内存分布及虚表
Derive :RTTI_COL x
vfTable for base A ---------------------------->> ------------------------------------
virtual Derive::fun1(overwrite
by derive class) for base A
data of base A virtual A::fun2(inherit from
base A) for base A
vfTable for base B . . . . . .
------------------------------------
data of base B virtual fun(if derive own virtual
data of Derive itself itslef) for derive * perhaps not
Figure 1:派生类实例对象内存分布及虚表映射
如上图,其中左部为派生类class的实例对象内存格局(继承来自A,B),其中第一项为base A的虚表地址(A,B数据在class实例中布局顺序是按照Derive在声明时继承顺序决定的),从图中箭头可知base A的虚表地址指向了一个数组,里面存放了Derive对应的虚函数地址:
① 首先存放重写过的base A声明的的虚函数地址(如果虚函数是从基类继承过来的,那么虚表中存放的也是base A中该函数地址)。
② 然后存放Derive自己声明的虚函数(可能没有)。
2. classX :RTTI Complete Object Locator {for x}
Field Length Remark
reserve_1 4 not used,filled with 0x00
offset_x 4 the offset of vfTable( for x) and
the base address of classX
reserve_3 4 not used,filled with 0x00
pTypeDescriptor 4 address of classX:RTTI Type Descriptor
pHierarchyDescriptor 4 address of classX:RTTI class Hierarchy Descriptor
Figure 2: classX : RTTI Complete Object Locator {for x}反汇编结构
offset_x字段描述 基类x在classX实例内存空间中的起始地址相对于classX基址的偏移(也就是x的vfTable字段在classX内存布局中的偏移)
pHierarchyDescriptor字段存放classX:RTTI class Hierarchy Descriptor 结构的地址,该结构描述了Derive类的内存结构层次信息。
3. classX:RTTI class Hierarchy Descriptor
Field Length Remark
reserve_1 4 unknown
reserve_2 4 unknown
dwArrayElemCount 4 the count of the element inside pBaseClassArray
pBaseClassArray 4 address of classX:RTTI Base class Array
Figure 3: classX:RTTI class Hierarchy Descriptor反汇编结构
该结构详细描述了类实例中相关重要信息的的索引
pBaseClassArray字段存放classX:RTTI Base class Array数组基址。
dwArrayElemCount字段存放classX:RTTI Base class Array数组项数,包括自身一项和每个基类一项。
4. classX:RTTI Base class Array
此数组存放了该类实例对象所需的所有布局信息。数组中每项均存放了一个类描述符classX:RTTI_BCD的地址,其中实例自身的类描述符地址放在数组第一项,然后存放基类描述符地址
5. classX:RTTI Base class Descriptor
Field Length Remark
pTypeDescriptor 4 address of classX:RTTI Type Descriptor
dwBaseClassCount 4 the count of Base class of classX
Offset_X 4 the offset of vfTable( for classX)
and the base address of Derive
reserve_1 4 unknown,filled with 0xffffffff
reserve_2 4 unknown,filled with 0x00000000
reserve_3 4 unknown,filled with 0x00000040
Figure 4: classX:RTTI Base class Descriptor反汇编结构
该结构中有几个特别需要注意的地方,首先该结构是从classX:RTTI class Hierarchy Descriptor –>classX:RTTI Base class Array引出的,所以此结构中的Offset_X数据都是相对于classX:RTTI class Hierarchy Descriptor中的classX对象而言
举例说明,从Derive:RTTI class Hierarchy Descriptor中引出的x:RTTI Base class Descriptor中的Offset_X 字段是x相对于Derive而言的;但是如果从x:RTTI class Hierarchy Descriptor中引出的x:RTTI Base class Descriptor中的Offset_X 字段则是x相对于x而言的
这个
Reversing Microsoft Visual C++ Part II: Classes, Methods and RTTI
struct RTTICompleteObjectLocator
{
DWORD signature; //always zero ?
DWORD offset; //offset of this vtable in the complete class
DWORD cdOffset; //constructor displacement offset
struct TypeDescriptor* pTypeDescriptor; //TypeDescriptor of the complete class
struct RTTIClassHierarchyDescriptor* pClassDescriptor; //describes inheritance hierarchy
};
struct RTTIClassHierarchyDescriptor
{
DWORD signature; //always zero?
DWORD attributes; //bit 0 set = multiple inheritance, bit 1 set = virtual inheritance
DWORD numBaseClasses; //number of classes in pBaseClassArray
struct RTTIBaseClassArray* pBaseClassArray;
};
struct RTTIBaseClassDescriptor
{
struct TypeDescriptor* pTypeDescriptor; //type descriptor of the class
DWORD numContainedBases; //number of nested classes following in the Base Class Array
struct PMD where; //pointer-to-member displacement info
DWORD attributes; //flags, usually 0
};
struct PMD
{
int mdisp; //member displacement
int pdisp; //vbtable displacement
int vdisp; //displacement inside vbtable
};