#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
请按任意键继续. . .