编译器 VC6
1. 类的虚函数
class CClassA
{
public:
CClassA();
virtual ~CClassA();
public:
int a;
void fn1();
virtual void fn2();
virtual void fn3();
};
class CClassB : public CClassA
{
public:
CClassB();
virtual ~CClassB();
public:
int a;
void fn1();
virtual void fn3();
virtual void fn4();
};
所有虚函数会出现在虚函数表(VTAB)中, 在VC编译模式下
虚函数表的第一项指向类析构函数. 父类的虚函数排在较前的位置
子类在构造时子类的虚表覆盖了父类的虚表
虚表放在类实例空间的第一个DWORD, 此后是类的数据成员
如下形式的ASM调用, 则类实例是动态创建的
.text:004011B8 mov eax, [esi]
.text:004011BA mov ecx, esi
.text:004011BC mov byte ptr [esp+20h+var_4], 0
.text:004011C1 call dword ptr [eax+8]
.text:004011C4 mov ecx, esi
.text:004011C6 call sub_401060 //类普通成员函数
.text:004011CB mov edx, [esi]
.text:004011CD mov ecx, esi
.text:004011CF call dword ptr [edx+4] //虚函数
.text:004011D2 mov eax, [esi]
.text:004011D4 mov ecx, esi
.text:004011D6 call dword ptr [eax+0Ch] //静态创建的类不会有此汇编形式
//直接是函数地址
ESI指向类实例首地址.
如果一个函数在二个虚表中出现, 则此函数在子类中没有实现. 为调用父类虚函数
如果子类有重新实现虚函数, 则此虚函数在父类和子类中各有实现, 虚表中不会重
复出现
[课程]FART 脱壳王!加量不加价!FART作者讲授!