继续利用昨天的那个多继承类的例子,然后在派生类里添加自己的构造函数与析构函数,修改如下:
class C: public A,public B{
private:
int a,b;
public:
void displayC(){
cout<<"function: displayC()\n";
}
C(){
cout<<"Constructor C\n";
}
~C(){
cout<<"Destructor C\n";
}
};
因为这里研究,这里如此修改,是为了更快的在IDA里定位。
用IDA打开编译后的EXE文件,定位到派生类的构造函数
.text:004010E0 sub_4010E0 proc near ; CODE XREF: sub_401000+28p
.text:004010E0
.text:004010E0 var_4 = dword ptr -4
.text:004010E0
.text:004010E0 push ebp
.text:004010E1 mov ebp, esp
.text:004010E3 push ecx
.text:004010E4 mov [ebp+var_4], ecx
.text:004010E7 mov ecx, [ebp+var_4] ; 利用ECX为传递当前对象的this指针
.text:004010EA call sub_401160 ; 调用基类:class A的构造函数来初始化
.text:004010EF mov ecx, [ebp+var_4]
.text:004010F2 add ecx, 10h ; 直接移动了第2个基类的偏移位置
.text:004010F2 ; 这里可以确定下来第一个基类的大小了,呵呵
.text:004010F5 call sub_401180 ; 调用基类:class B的构造函数来初始化
.text:004010FA mov eax, [ebp+var_4]
.text:004010FD mov dword ptr [eax], offset off_41420C
.text:00401103 mov ecx, [ebp+var_4]
.text:00401106 mov dword ptr [ecx+10h], offset off_414204
.text:0040110D push offset aConstructorC ; "Constructor C\n"
.text:00401112 push offset unk_41A428
.text:00401117 call sub_4011A0
.text:0040111C add esp, 8
.text:0040111F mov eax, [ebp+var_4]
.text:00401122 mov esp, ebp
.text:00401124 pop ebp
.text:00401125 retn
.text:00401125 sub_4010E0 endp
结合我们昨天得到的信息:
class C size(40):
+---
| +--- (base class A)
0 | | {vfptr}
4 | | ch
| | <alignment member> (size=3)
8 | | a
12 | | b
| +---
| +--- (base class B)
16 | | {vfptr}
20 | | ch
| | <alignment member> (size=3)
24 | | a
28 | | b
| +---
32 | a
36 | b
+---
这样就更清晰了,呵呵!我们再利用一下IDA的插件来看一下: