C++继承虚表检查

#include <iostream>
#include <string>
using namespace std;

typedef unsigned int u32;

class CMyClassA
{
public:
	virtual void DoSomethingA1()
	{
		cout << __FUNCTION__ << endl;
		a = 1;
	}

	virtual void DoSomethingA2()
	{
		cout << __FUNCTION__ << endl;
	}

	int a;
};

class CMyClassB
{
public:
	virtual void DoSomethingB1()
	{
		cout << __FUNCTION__ << endl;
		b = 2;
	}

	virtual void DoSomethingB2()
	{
		cout << __FUNCTION__ << endl;
	}

	int b;
};

class CMyClassC : public CMyClassA, public CMyClassB
{
public:
	virtual void DoSomethingC1()
	{
		cout << __FUNCTION__ << endl;
		c = 3;

		void (CMyClassA::*func)(void) = &CMyClassA::DoSomethingA1;
		(this->*func)();

		__asm
		{
			mov eax, func
		}

		void (CMyClassC::*func2)(void) = &CMyClassC::DoSomethingA1;
		(this->*func2)();
	}

	virtual void DoSomethingC2()
	{
		cout << __FUNCTION__ << endl;
	}

	int c;
};

//
class CX
{
public:
	virtual void DoX1()
	{
		cout << __FUNCTION__ << endl;
		x = 1;
	}

	int x;
};

class CY : public CX
{
public:
	virtual void DoY1()
	{
		cout << __FUNCTION__ << endl;
		y = 2;
	}

	int y;
};

class CZ : public CY
{
public:
	virtual void DoZ1()
	{
		cout << __FUNCTION__ << endl;
		z = 3;
	}

	int z;
};

//
class CP
{
public:
	virtual void DoP1()
	{
		cout << __FUNCTION__ << endl;
	}

	int p;
};

class __declspec(novtable) CQ : public CP
{
public:
	virtual void DoQ1()
	{
		cout << __FUNCTION__ << endl;
	}

	int q;
};

int _tmain(int argc, _TCHAR* argv[])
{
	int i = 0;
// 	cout.setf(ios_base::hex, ios_base::dec);
	CMyClassC myc;

	cout << sizeof(myc) << endl;
	cout << endl;

	cout << "CMyClassC this : " << &myc << endl;
	cout << "a : " << &myc.a << endl;
	cout << "b : " << &myc.b << endl;
  	cout << "c : " << &myc.c << endl;
	cout << endl;

	cout << "vtbl ===" << endl;
	u32* pvtblC = *((u32**)(&myc));
	for(i = -3; i <= 6; i++)
	{
		cout << "vtbl " << i << " : " << *(pvtblC + i) << endl;
	}
	cout << endl;

	cout << "vtbl2 ===" << endl;
	u32* pvtblC2 = *((u32**)(&myc) + 2);
	for(i = -3; i <= 6; i++)
	{
		cout << "vtbl2 " << i << " : " << *(pvtblC2 + i) << endl;
	}
	cout << endl;

	cout << &CMyClassC::DoSomethingA1 << endl;
	cout << &CMyClassC::DoSomethingA2 << endl;
	cout << &CMyClassC::DoSomethingB1 << endl;
	cout << &CMyClassC::DoSomethingB2 << endl;
	cout << &CMyClassC::DoSomethingC1 << endl;
	cout << &CMyClassC::DoSomethingC2 << endl;
	cout << &CMyClassB::DoSomethingB1 << endl;
	cout << &CMyClassB::DoSomethingB2 << endl;
	cout << endl;

	cout << "vtbl ===" << endl;
	__asm
	{
		xor ecx, ecx
L1:
		cmp ecx, 0x3
		ja L2

		mov eax, 0x4
		mul ecx
		add eax, pvtblC
		mov edx, dword ptr [eax]
		push ecx
		lea ecx, myc
		call edx
		pop ecx

		inc ecx
		jmp L1
L2:
	}

	cout << endl;
	cout << "vtbl2 ===" << endl;
	__asm
	{
		lea eax, myc
		add eax, 0x8
		mov eax, dword ptr [eax]
		mov edx, dword ptr [eax]
		lea ecx, myc
		push eax
		mov eax, ecx
		add eax, 0x8
		mov ecx, eax
		pop eax
		push eax
		push ecx
		call edx

		pop ecx
		pop eax
		add eax, 0x4
		mov edx, dword ptr [eax]
		call edx
	}

	cout << endl;
	cout << "var ===" << endl;
	cout << "a : " << myc.a << endl;
	cout << "b : " << myc.b << endl;
	cout << "c : " << myc.c << endl;
	cout << endl;

	//
	{
		CZ cz;
		cout.setf(ios_base::hex);
		cout << "cz this : " << &cz << endl;
		cout << "x : " << &cz.x << endl;
		cout << "y : " << &cz.y << endl;
		cout << "z : " << &cz.z << endl;
		cout << endl;

		u32* pvtblz = *((u32**)&cz);
		int j;
		for(j = -2; j <= 5; j++)
		{
			cout << "pvtblz " << j << " : " << *(pvtblz + j) << endl;
		}
		cout << endl;

		__asm
		{
			xor ecx, ecx
L3:
			cmp ecx, 0x2
			ja L4

			mov eax, 0x4
			mul ecx
			add eax, pvtblz
			mov edx, dword ptr [eax]
			push ecx
			lea ecx, cz
			call edx
			pop ecx

			inc ecx
			jmp L3
L4:
		}

		cout << endl;
		cout << "var ===" << endl;
		cout << "x : " << cz.x << endl;
		cout << "y : " << cz.y << endl;
		cout << "z : " << cz.z << endl;
	}

// 	cout << 4 * 256 * 256 * 16 + 1 * 256 * 256 + 11 * 256 * 16 + 1 * 256 + 2 * 16 + 11 << endl;

	//
	cout << endl;
	cout << "sizeof(CP) = " << sizeof(CP) << endl;
	cout << "sizeof(CQ) = " << sizeof(CQ) << endl;

	cout << endl;
	system("pause");
	return 0;
}


VS2003输出:

20

CMyClassC this : 0018FE80
a : 0018FE84
b : 0018FE8C
c : 0018FE90

vtbl ===
vtbl -3 : 4302330
vtbl -2 : 4302645
vtbl -1 : 0
vtbl 0 : 4305200
vtbl 1 : 4302835
vtbl 2 : 4303205
vtbl 3 : 4302785
vtbl 4 : 0
vtbl 5 : 1132023107
vtbl 6 : 1936941420

vtbl2 ===
vtbl2 -3 : 975205225
vtbl2 -2 : 32
vtbl2 -1 : 0
vtbl2 0 : 4302330
vtbl2 1 : 4302645
vtbl2 2 : 0
vtbl2 3 : 4305200
vtbl2 4 : 4302835
vtbl2 5 : 4303205
vtbl2 6 : 4302785

1
1
1
1
1
1
1
1

vtbl ===
CMyClassA::DoSomethingA1
CMyClassA::DoSomethingA2
CMyClassC::DoSomethingC1
CMyClassA::DoSomethingA1
CMyClassA::DoSomethingA1
CMyClassC::DoSomethingC2

vtbl2 ===
CMyClassB::DoSomethingB1
CMyClassB::DoSomethingB2

var ===
a : 1
b : 2
c : 3

cz this : 0018FE50
x : 0018FE54
y : 0018FE58
z : 0018FE5C

pvtblz -2 : 0
pvtblz -1 : 0
pvtblz 0 : 4304765
pvtblz 1 : 4302960
pvtblz 2 : 4301820
pvtblz 3 : 0
pvtblz 4 : 976902211
pvtblz 5 : 827879236

CX::DoX1
CY::DoY1
CZ::DoZ1

var ===
x : 1
y : 2
z : 3

sizeof(CP) = 8
sizeof(CQ) = 12

请按任意键继续. . .


 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值