当前位置: 首页 > news >正文

Windows逆向工程入门之结构体类特性分析

  • 公开视频 -> 链接点击跳转公开课程
  • 博客首页 -> ​​​链接点击跳转博客主页

目录

基本特性

构造函数

静态成员

常量成员

继承构造

继承(单)

继承(多)

继承(菱)

多态(单)

多态(多)

虚表(单)

虚表(多)

纯虚


基本特性

#include <iostream>
#include <Windows.h>

struct MyStruct
{
	//public:
	int age;
};

class Person
{
	//private:
	int age;

public:
	int a;
	int b;

//public:
//	int c;
//	int d;
//	int e;
//	int f;
//	int g;

public:
	static int ver;

public:

	void SetData(int a, int b)
	{
		this->a = a;
		this->b = b;

		/*
		
		0040105C 51                   push        ecx

		0040106C 59                   pop         ecx

		0040106D 89 4D F8             mov         dword ptr [ebp-8],ecx

		0040107A 8B 45 F8             mov         eax,dword ptr [ebp-8]
		0040107D 8B 4D 08             mov         ecx,dword ptr [ebp+8]
		00401080 89 08                mov         dword ptr [eax+0],ecx

		00401082 8B 45 F8             mov         eax,dword ptr [ebp-8]
		00401085 8B 4D 0C             mov         ecx,dword ptr [ebp+0Ch]
		00401088 89 48 04             mov         dword ptr [eax+4],ecx
		
		*/

	}

	void _cdecl SetDataa(int a)
	{
		this->a = a;

		/*
		
			004010D1 8B 45 08             mov         eax,dword ptr [ebp+8]
			004010D4 8B 4D 0C             mov         ecx,dword ptr [ebp+0Ch]
			004010D7 89 08                mov         dword ptr [eax],ecx
		
		*/

	}

	void _stdcall SetDatab(int b)
	{
		this->b = b;

		/*
		
			00401111 8B 45 08             mov         eax,dword ptr [ebp+8]
			00401114 8B 4D 0C             mov         ecx,dword ptr [ebp+0Ch]
			00401117 89 48 04             mov         dword ptr [eax+4],ecx
			0040112D C2 08 00             ret         8  

		*/

	}

	void _fastcall SetDataab(int a, int b)
	{
		this->a = a;
		this->b = b;

		/*
		
			0040110D 89 55 F8             mov         dword ptr [ebp-8],edx  
			00401110 89 4D EC             mov         dword ptr [ebp-14h],ecx  

			0040111D 8B 45 EC             mov         eax,dword ptr [ebp-14h]  
			00401120 8B 4D F8             mov         ecx,dword ptr [ebp-8]  
			00401123 89 08                mov         dword ptr [eax],ecx  
			00401125 8B 45 EC             mov         eax,dword ptr [ebp-14h]  
			00401128 8B 4D 08             mov         ecx,dword ptr [ebp+8]  
			0040112B 89 48 04             mov         dword ptr [eax+4],ecx  
		
		*/
	}

public:

	// 函数重载
	Person()
	{
		a = 1;
		b = 2;
	}

	Person(int a)
	{
		this->a = a;
	}

	Person(int a, int b)
	{
		this->a = a;
		this->b = b;
	}

	~Person()
	{
		a = 0;
		b = 0;
	}

};

int Person::ver = 1;

int g_Num = 1;

Person g_Obj;

void SetData(int* a, int* b)
{
	*a = 1;
	*b = 1;
}

void classParam1(Person per)
{

}

void classParam2(Person* p)
{

}

void classParam2()
{

}

Person retClass()
{
	Person obj;
	return obj;
}

Person* retClassptr()
{
	return NULL;
}

int main()
{
	
	Person obj;
	Person* p = &obj;
	Person obj1;
	Person obj2;

	// 成员偏移
	{
		
		p->a = 1;
		p->b = 2;

		printf("%d \r\n", &((Person*)NULL)->b);

		/*

			0x0019FED4  00 00 00 00  ....
			0x0019FED8  00 00 00 00  ....

			Person obj = { 0 };
			004010BF 33 C0                xor         eax,eax
			004010C1 89 45 F0             mov         dword ptr [ebp-10h],eax
			004010C4 89 45 F4             mov         dword ptr [ebp-0Ch],eax

			Person* p = &obj;
			004010C7 8D 45 F0             lea         eax,[ebp-10h]
			004010CA 89 45 E4             mov         dword ptr [ebp-1Ch],eax

			p->a = 1;
			004010CD 8B 45 E4             mov         eax,dword ptr [ebp-1Ch]
			004010D0 C7 00 01 00 00 00    mov         dword ptr [eax+0],1

			p->b = 2;
			004010D6 8B 45 E4             mov         eax,dword ptr [ebp-1Ch]
			004010D9 C7 40 04 02 00 00 00 mov         dword ptr [eax+4],2

		*/

		int a = 2;
		int b = 2;
		SetData(&a, &b);

		int a1 = 2;
		int b1 = 2;
		SetData(&a1, &b1);
	}

	// 调用约定
	{
		// this call
		obj1.SetData(1, 1);
		obj2.SetData(2, 2);

		/*

			this call

			obj1.SetData(1, 1);
			0040128B 6A 01                push        1
			0040128D 6A 01                push        1
			0040128F 8D 4D A4             lea         ecx,[ebp-5Ch]  ****
			00401292 E8 B9 FD FF FF       call        00401050

			obj2.SetData(2, 2);
			00401297 6A 02                push        2
			00401299 6A 02                push        2
			0040129B 8D 4D 94             lea         ecx,[ebp-6Ch]	 ****
			0040129E E8 AD FD FF FF       call        00401050

		*/

		// _cdecl
		obj1.SetDataa(1);

		/*

			004012E3 6A 01                push        1
			004012E5 8D 45 A4             lea         eax,[ebp-5Ch]
			004012E8 50                   push        eax
			004012E9 E8 C2 FD FF FF       call        004010B0
			004012EE 83 C4 08             add         esp,8

		*/

		// _stdcall
		obj1.SetDatab(1);

		/*

			00401331 6A 01                push        1
			00401333 8D 45 A4             lea         eax,[ebp-5Ch]
			00401336 50                   push        eax
			00401337 E8 B4 FD FF FF       call        004010F0

		*/

		// _fastcall
		obj1.SetDataab(1, 2);

		/*

			0040139C 6A 02                push        2
			0040139E BA 01 00 00 00       mov         edx,1
			004013A3 8D 4D A4             lea         ecx,[ebp-5Ch]
			004013A6 E8 45 FD FF FF       call        004010F0

		*/
	}

	// 成员内存
	{
		printf("%d \r\n", sizeof(Person));

		p->a = 1;
		p->b = 2;
		p->ver = 3;

		/*

			004013D2  mov         eax,dword ptr [ebp-1Ch]  
			004013D5  mov         dword ptr [eax+0],1  

			004013DB  mov         eax,dword ptr [ebp-1Ch]  
			004013DE  mov         dword ptr [eax+4],2  

			004013E5  mov         dword ptr ds:[00407000h],3  
		
		*/

		obj1.ver = 1;
		obj2.ver = 2;
		Person::ver = 3;

		/*
		
			004013D7  mov         dword ptr ds:[00407000h],1
			004013E1  mov         dword ptr ds:[00407000h],2
			004013EB  mov         dword ptr ds:[00407000h],3
		
		*/
	}

	// 参数传递
	{
		classParam1(obj);

		/*
		
			int a;
			int b;

			00401435  mov         eax,dword ptr [ebp-0Ch]  
			00401438  push        eax  
			00401439  mov         ecx,dword ptr [ebp-10h]  
			0040143C  push        ecx  
			0040143D  call        00401210  
			00401442  add         esp,8  
		
		*/

		/*
		
			public:

				int a;
				int b;

			public:
				int c;

			00401438  sub         esp,0Ch

			0040143B  mov         eax,esp

			0040143D  mov         ecx,dword ptr [ebp-14h]
			00401440  mov         dword ptr [eax+0],ecx

			00401442  mov         edx,dword ptr [ebp-10h]
			00401445  mov         dword ptr [eax+4],edx

			00401448  mov         ecx,dword ptr [ebp-0Ch]
			0040144B  mov         dword ptr [eax+8],ecx
			
			0040144E  call        00401210
			00401453  add         esp,0Ch

		*/


		/*
		
			public:
				int a;
				int b;

			public:
				int c;
				int d;
				int e;
				int f;
				int g;

			0040145F  sub         esp,1Ch
			00401462  mov         ecx,7
			00401467  lea         esi,[ebp-24h]
			0040146A  mov         edi,esp
			0040146C  rep movs    dword ptr es:[edi],dword ptr [esi]

			0040146E  call        00401210
			00401473  add         esp,1Ch

		
		*/

		classParam2(&obj);
		/*
		
			004014B6  lea         eax,[ebp-24h]
			004014B9  push        eax
			004014BA  call        00401250
			004014BF  add         esp,4
		
		*/
	}

	// 对象返回
	{
		Person obj = retClass();

		/*
		
			public:
				int a;
				int b;

			00401564  call        00401290  
			00401569  mov         dword ptr [ebp+FFFFFEB4h],eax  
			0040156F  mov         dword ptr [ebp+FFFFFEB8h],edx  
			00401575  mov         eax,dword ptr [ebp+FFFFFEB4h]  
			0040157B  mov         ecx,dword ptr [ebp+FFFFFEB8h]  
			00401581  mov         dword ptr [ebp-7Ch],eax  
			00401584  mov         dword ptr [ebp-78h],ecx  
		
		*/

		/*
		
			public:
				int a;
				int b;

			public:
				int c;

			00401585  lea         eax,[ebp+FFFFFE8Ch]  
			0040158B  push        eax  
			0040158C  call        00401290  
			00401591  add         esp,4  

			00401594  mov         ecx,dword ptr [eax+0]  
			00401596  mov         dword ptr [ebp+FFFFFEA0h],ecx  
			0040159C  mov         edx,dword ptr [eax+4]  
			0040159F  mov         dword ptr [ebp+FFFFFEA4h],edx  
			004015A5  mov         eax,dword ptr [eax+8]  
			004015A8  mov         dword ptr [ebp+FFFFFEA8h],eax  

			004015AE  mov         ecx,dword ptr [ebp+FFFFFEA0h]  
			004015B4  mov         dword ptr [ebp+FFFFFF74h],ecx  
			004015BA  mov         edx,dword ptr [ebp+FFFFFEA4h]  
			004015C0  mov         dword ptr [ebp+FFFFFF78h],edx  
			004015C6  mov         eax,dword ptr [ebp+FFFFFEA8h]  
			004015CC  mov         dword ptr [ebp+FFFFFF7Ch],eax 
		
		*/
	}

	// 构造析构
	{

		// 局部对象
		{
			Person obj111;

			printf("Test\r\n");

			/*

				00401695  lea         ecx,[ebp-98h]
				0040169B  call        Person::Person (0401000h)

				004016A0  push        offset string "Test\r\n" (0405160h)
				004016A5  call        printf (04017C0h)
				004016AA  add         esp,4

				004016AD  lea         ecx,[ebp-98h]
				004016B3  call        Person::~Person (0401060h)

			*/
		}

		// 堆对象
		{
			Person* pObj = new Person;
			int a = 1;
			if (pObj)
			{
				delete pObj;
				pObj = NULL;
			}

			pObj = (Person*)malloc(sizeof(Person));
			if (pObj)
			{
				free(pObj);
				pObj = NULL;
			}
		}

	}

	// 数据权限
	{
		MyStruct str;
		Person obj;

		str.age = 18;

		//编译器限制
		//obj.age = 18;
		int* p = (int*)&obj;
		obj.a = 11;
		obj.b = 2;;
		p[0] = 0xCC;
		p[1] = 0xCC;
		p[2] = 0xCC;

		char* pp = (char*)&obj;
		/*
			char
			int
			short

			CC XX XX XX
			CC CC CC CC
			CC CC XX XX
	
		*/

		pp[0] = 0x11;

		*(int*)(pp + 4) = 0x22222222;
		*(short*)(pp + 8) = 0x3333;

	}


	return 3;
}

构造函数

#include <iostream>

class Person
{
public:
	int m_Age;
	int m_Height;

public:
	char* m_Addr;

public:
	// 构造函数

	//Person() = delete;
	//Person(const Person&) = delete;

	Person()
	{
		this->m_Age = 0;
		this->m_Height = 0;
		this->m_Addr = 0;	
	}

	Person(int nAge)
	{
		this->m_Age = nAge;
		this->m_Height = 0;
		this->m_Addr = 0;
	}

	Person(int nAge, int nHeight)
	{
		this->m_Age = nAge;
		this->m_Height = nHeight;
		this->m_Addr = 0;
	}

	Person(char nAge, int nHeight = 0, int nAddr = 0)
	{
		this->m_Age = nAge;
		this->m_Height = nHeight;
		this->m_Addr = (char*)nAddr;
	}

	Person(const Person& obj)
	{
		// 深拷贝 与 浅拷贝
		this->m_Age = obj.m_Age;
		this->m_Height = obj.m_Height;
		if (obj.m_Addr != NULL)
		{
			this->m_Addr = (char*)malloc(20);
		}
		else
		{
			this->m_Addr = obj.m_Addr;
		}
	}

	~Person()
	{
		if (this->m_Addr != NULL)
		{
			free(this->m_Addr);
			this->m_Addr = NULL;
		}
	}

};

// 函数重载
void Fun()
{

}

void Fun(int a)
{

}

int main()
{
	Person obj1;
	Person obj2(18);
	Person obj3(18, 180);
	//Person obj4(18, 180, 10);

	/*
		
		this call -> lea ecx, xx
		
		004010B9  lea         ecx,[obj1]
		004010BC  call        Person::Person (0401060h)

		004010C1  push        12h
		004010C3  lea         ecx,[obj2]
		004010C6  call        Person::Person (0401000h)

		004010CB  push        0B4h
		004010D0  push        12h
		004010D2  lea         ecx,[obj3]
		004010D5  call        Person::Person (0401030h)
	
	*/

	Person obj4(obj3);
	/*
	
		004010DA  mov         eax,dword ptr [obj3]  
		004010DD  mov         ecx,dword ptr [ebp-14h]  
		004010E0  mov         dword ptr [obj4],eax  
		004010E3  mov         dword ptr [ebp-1Ch],ecx 
	
	*/

	Person obj5;
	obj5 = obj4;
	/*
	
		004010E6  lea         ecx,[obj5]
		004010E9  call        Person::Person (0401060h)

		004010EE  mov         eax,dword ptr [obj4]
		004010F1  mov         ecx,dword ptr [ebp-1Ch]
		004010F4  mov         dword ptr [obj5],eax
		004010F7  mov         dword ptr [ebp-24h],ecx
	
	*/

	Person obj6;
	obj6.m_Addr = (char*)malloc(20);

	Person obj7(obj6);

	Person obj8(1, 2);

	return 0;
}

静态成员

#include <iostream>

class Person
{
public:
	int m_A;

public:
	// 静态成员

	// 静态变量
	static int ver;

	// 静态函数
	static int Add(int a, int b)
	{
		//m_A = 1;
		ver = 3;
		return a + b;
	}
};

int Person::ver = 1;

int main()
{
	Person obj1;
	Person obj2;

	obj1.m_A = 1;
	obj2.m_A = 1;

	obj1.ver = 2;
	obj2.ver = 3;
	Person::ver = 4;

	/*
	
		00401029  mov         dword ptr [Person::ver (0404000h)],2  
		00401033  mov         dword ptr [Person::ver (0404000h)],3  
		0040103D  mov         dword ptr [Person::ver (0404000h)],4 
	
	*/

	obj1.Add(1, 2);
	obj2.Add(2, 3);
	Person::Add(3, 4);

	/*
	
		00401067  push        2  
		00401069  push        1  
		0040106B  call        Person::Add (0401000h)  
		00401070  add         esp,8  

		00401073  push        3  
		00401075  push        2  
		00401077  call        Person::Add (0401000h)  
		0040107C  add         esp,8  

		0040107F  push        4  
		00401081  push        3  
		00401083  call        Person::Add (0401000h)  
		00401088  add         esp,8  
	
	*/


	return 0;
}

常量成员

#include <iostream>

class Person
{
public:
	int m_A;

public:
	const int m_B;

public:
	mutable int m_C;

public:
	Person(int a, int b) : m_A(a), m_B(b)
	{

	}

public:
	void GetInfo() const
	{
		//m_A = 1;
		//m_B = 2;
		m_C = 0xCC;
	}

};

Person g_Obj(0xCC, 0xFF);

int main()
{
	g_Obj.m_A = 1;
	//g_Obj.m_B = 2;

	Person* p = &g_Obj;
	//p->m_B = 2;

	int* pp = (int*)&g_Obj;
	pp[1] = 2;

	g_Obj.GetInfo();

	Person obj1(1,2);
	Person obj2(2,3);

	/*
	
		00401049  lea         ecx,[obj1]
		0040104C  call        Person::Person (0401000h)

		00401051  lea         ecx,[obj2]
		00401054  call        Person::Person (0401000h)
		

		00401000  push        ebp
		00401001  mov         ebp,esp
		00401003  sub         esp,44h

		00401006  push        ebx
		00401007  push        esi
		00401008  push        edi

		00401009  mov         dword ptr [this],ecx
		0040100C  mov         eax,dword ptr [this]
		0040100F  mov         dword ptr [eax+4],1
		00401016  mov         eax,dword ptr [this]

		00401019  pop         edi
		0040101A  pop         esi
		0040101B  pop         ebx

		0040101C  mov         esp,ebp
		0040101E  pop         ebp
		0040101F  ret
	*/

	return 0;
}

继承构造

#include <iostream>
#include <Windows.h>

class Base
{
public:
	int m_A;

	Base()
	{
		std::cout << "Base" << std::endl;
		m_A = 1;
	}

	~Base()
	{
		std::cout << "~Base" << std::endl;
		m_A = 0;
	}
};

class Son1 : public Base
{
public:
	int m_A;

	Son1()
	{
		std::cout << "Son1" << std::endl;
		m_A = 2;
	}

	~Son1()
	{
		std::cout << "~Son1" << std::endl;
		m_A = 0;
	}
};

int main()
{
	Son1 objSon;

	/*
	
		00401079  lea         ecx,[objSon]
		0040107C  call        Son1::Son1 (0401020h)

			00401029  mov         dword ptr [this],ecx 
			0040102C  mov         ecx,dword ptr [this]  
			0040102F  call        Base::Base (0401000h) 

				00401009  mov         dword ptr [this],ecx
				0040100C  mov         eax,dword ptr [this]
				0040100F  mov         dword ptr [eax],1
				00401015  mov         eax,dword ptr [this]

			00401034  mov         eax,dword ptr [this]  
			00401037  mov         dword ptr [eax+4],2  
			0040103E  mov         eax,dword ptr [this]  

		
		004017B8  lea         ecx,[objSon]
		004017BB  call        Son1::~Son1 (04015E0h)

			004015E9  mov         dword ptr [this],ecx  
			004015EC  mov         eax,dword ptr [this]  
			004015EF  mov         dword ptr [eax+4],0  
			004015F6  mov         ecx,dword ptr [this]  
			004015F9  call        Base::~Base (04015C0h) 

				004015C9  mov         dword ptr [this],ecx  
				004015CC  mov         eax,dword ptr [this]  
				004015CF  mov         dword ptr [eax],0 

	*/
	

	return 0;
}

继承(单)

#include <iostream>
#include <Windows.h>

class Base
{
public:
	int m_A;
	Base()
	{
		std::cout << "Base" << std::endl;
		m_A = 1;
	}
};

class Son1 : public Base
{
public:
	int m_B;
	Son1()
	{
		std::cout << "Son1" << std::endl;
		m_B = 2;
	}
};

class Son2 : public Son1
{
public:
	int m_C;
	Son2()
	{
		std::cout << "Son2" << std::endl;
		m_C = 3;
	}
};

int main()
{
	std::cout << sizeof(Base) << std::endl;
	std::cout << sizeof(Son1) << std::endl;
	std::cout << sizeof(Son2) << std::endl;
	
	Son2 objSon;
	objSon.m_A = 1;
	objSon.m_B = 2;
	objSon.m_C = 3;

	/*
	
		LEA ECX, OBJADDR
		CALL SON2::SON2
			
			MOV ECX, THIS
			CALL SON1::SON1
				
				MOV ECX, THIS
				CALL BASE::BASE
					
					MOV M_A, 1

				MOV M_B, 2

			MOV M_C, 3
		
	
	*/
	

	return 0;
}

继承(多)

#include <iostream>
#include <Windows.h>

class Base1
{
public:
	int m_A;
	Base1()
	{
		m_A = 1;
	}
};

class Base2
{
public:
	int m_B;
	Base2()
	{
		m_B = 2;
	}
};

class Son1 : public Base1, public Base2
{
public:
	int m_C;
	Son1()
	{
		m_C = 3;
	}
};

int main()
{
	std::cout << sizeof(Base1) << std::endl;
	std::cout << sizeof(Base2) << std::endl;
	std::cout << sizeof(Son1) << std::endl;
	
	Son1 obj;
	obj.m_A = 1;
	obj.m_B = 2;
	obj.m_C = 3;

	/*
		
		LEA ECX, OBJADDR
		CALL SON1::SON1
			
			MOV ECX, THIS
			CALL BASE1::BASE1
				MOV M_A, 1

			MOV ECX, THIS
			CALL BASE2::BASE2
				MOV M_B, 2

			MOV M_C, 3
	
	*/

	return 0;
}

继承(菱)

#include <iostream>
#include <Windows.h>

class Base
{
public:
	int m_A;
	Base()
	{
		m_A = 1;
	}

};

class Dev1 : public Base
{
public:
	int m_B;
	Dev1()
	{
		m_B = 2;
	}
};

class Dev2 : public Base
{
public:
	int m_C;
	Dev2()
	{
		m_C = 3;
	}
};

class Son : public Dev1, public Dev2
{
public:
	int m_D;
	Son()
	{
		m_D = 4;
	}
};

int main()
{
	/*
			基类
			/  \
		派生		派生
			\  /
			子类
	
	*/

	std::cout << sizeof(Base) << std::endl;
	std::cout << sizeof(Dev1) << std::endl;
	std::cout << sizeof(Dev2) << std::endl;
	std::cout << sizeof(Son) << std::endl;

	Son obj;

	/*
	
		0x0019FED0  01 00 00 00  ....
		0x0019FED4  02 00 00 00  ....

		0x0019FED8  01 00 00 00  ....
		0x0019FEDC  03 00 00 00  ....

		0x0019FEE0  04 00 00 00  ....
	
	*/

	/*
	
		LEA ECX, OBJADDR
		CALL SON::SON
			
			MOV ECX, THIS
			CALL DEV1::DEV1
				
				MOV ECX, THIS
				CALL BASE::BASE

					MOV M_A, 1
				
				MOV M_B, 1

			MOV ECX, THIS
			CALL DEV2::DEV2

				MOV ECX, THIS
				CALL BASE::BASE
					
					MOV M_A, 1

				MOV M_c, 1

			MOV M_D, 4
	
	
	*/

	return 0;
}

多态(单)

#include <iostream>
#include <Windows.h>

class Animal
{
public:
	int m_A;

public:
	virtual void MakeSound()
	{
		std::cout << "Animal::MakeSound" << std::endl;
	}
};

class Dog : public Animal 
{
public:
	int m_B;

public:
	void MakeSound() override
	{
		std::cout << "Dog::MakeSound" << std::endl;
	}
};

class Cat : public Animal
{
public:
	int m_C;

public:
	void MakeSound() override
	{
		std::cout << "Cat::MakeSound" << std::endl;
	}
};

int main()
{
	Animal anm;
	Dog dog;
	Cat cat;
	/*
	
		004017D9  lea         ecx,[anm]
		004017DC  call        Animal::Animal (04013E0h)
		004017E1  lea         ecx,[dog]
		004017E4  call        Dog::Dog (0401430h)
		004017E9  lea         ecx,[cat]
		004017EC  call        Cat::Cat (0401400h)
	
		004013E9  mov         dword ptr [this],ecx  
		004013EC  mov         eax,dword ptr [this]  
		004013EF  mov         dword ptr [eax],offset Animal::`vftable' (0404154h)  
		004013F5  mov         eax,dword ptr [this]  

		多态机制
			__vfptr		-> 虚函数指针
				mov         dword ptr [eax],offset Animal::`vftable' (0404154h)

			__vftablr	-> 虚函数表
				0x00404154  80 16 40 00  €.@.
				0x00404158  41 6e 69 6d  Anim
				0x0040415C  61 6c 3a 3a  al::
				0x00404160  4d 61 6b 65  Make

			__vfaddr	-> 虚函数地址
				0x00401680	Animal::MakeSound(void):
	*/

	std::cout << sizeof(Animal) << std::endl;
	std::cout << sizeof(Dog) << std::endl;
	std::cout << sizeof(Cat) << std::endl;
	
	int* vfptr = (int*)(*(int*)(&anm));
	int vfaddr1 = vfptr[0];
	int vfaddr2 = vfptr[1];

	Animal* parPtr;

	parPtr = &dog;
	parPtr->MakeSound();

	/*
	
		0040186A  lea         eax,[dog]  
		0040186D  mov         dword ptr [parPtr],eax  

		00401870  mov         eax,dword ptr [parPtr]	dog.Addr

		00401873  mov         edx,dword ptr [eax]		dog.vtftable

		00401875  mov         ecx,dword ptr [parPtr]	dog.Addr

		00401878  mov         eax,dword ptr [edx]		dog.vtfaddr
		0040187A  call        eax  
	
	*/

	parPtr = &cat;
	parPtr->MakeSound();

	return 0;
}

多态(多)

#include <iostream>
#include <Windows.h>

class Base1
{
public:
	int m_A = 1;
public:
	virtual void Fun1() {}
};

class Base2
{
public:
	int m_B = 2;
public:
	virtual void Fun2() {}
};

class Son : public Base1, public Base2
{
public:
	int m_C = 3;
public:
	virtual void Fun1() {}
	virtual void Fun2() {}
};

int main()
{
	std::cout << sizeof(Base1) << std::endl;
	std::cout << sizeof(Base2) << std::endl;
	std::cout << sizeof(Son) << std::endl;

	Son obj;

	/*
		
		Son
		+0	vfptr1
		+4  vfptr2
		+8	var

		004011BA  lea         ecx,[obj]
		004011BD  call        Son::Son (0401080h)

		00401089  mov         dword ptr [this],ecx

		0040109F  mov         eax,dword ptr [this]
		004010A2  mov         dword ptr [eax],offset Son::`vftable' (040312Ch)

		004010A8  mov         eax,dword ptr [this]
		004010AB  mov         dword ptr [eax+4],offset Son::`vftable' (0403134h)
		
		0x0019FEDC  2c 31 40 00  ,1@.	Base1.vftable
					0x0040312C  e0 10 40 00		reverse.exe!Son::Fun1(void)

		0x0019FEE0  34 31 40 00  41@.	Base2.vftable
					0x00403134  20 11 40 00		reverse.exe!Son::Fun2(void)
	*/

	int vfaddr1 = *(PDWORD)((PUCHAR)(&obj) + 0);
	int vfaddr2 = *(PDWORD)((PUCHAR)(&obj) + 4);

	/*
		
		父类1 -> 虚函数指针 -> 成员变量
		0x0019FED0  2c 31 40 00  ,1@.
		0x0019FED4  01 00 00 00  ....

		父类2 -> 虚函数指针 -> 成员变量
		0x0019FED8  34 31 40 00  41@.
		0x0019FEDC  02 00 00 00  ....

		子类
		0x0019FEE0  03 00 00 00  ....
	
	*/

	return 0;
}

虚表(单)

#include <iostream>
#include <Windows.h>

class Person1
{
public:
	int m_A;

public:
	const int m_B = 1;

public:
	void Fun1() {}

public:
	static int ver;
	static int Fun2() {}
};

int Person1::ver = 0;

class Base1
{
public:
	virtual void Fun1() {}

public:
	int m_A = 1;

protected:
	int m_B = 2;

private:
	int m_C = 3;
};

class Base2 : public Base1
{
public:
	virtual void Fun2() {}

public:
	int m_A = 5;
};

class Son1 : public Base2
{
	/*
	
		public:
			int m_A;

		protected:
			int m_B;

		private:
			int m_C;
	
	*/

public:
	virtual void Fun1() override {}
	virtual void Fun2() override {}

public:
	int m_D = 4;
};

int main()
{
	// 对象模型

	{
		// 数据类型 标识符 = 初始值;
		Person1 obj = {};
		std::cout << sizeof(obj) << std::endl;

		// 空的类对象占用内存空间1字节,需要为对应的变量分配内存空间

		obj.Fun1();

		/*
		
			004010A9  lea         ecx,[ebp-1]
			004010AC  call        Person1::Fun (0401040h)
		
		*/

		// 类对象中的普通成员函数不会占用内存空间

		obj.ver = 1;

		// 类对象中的静态成员不会占用内存空间
	}

	{
		std::cout << sizeof(Base1) << std::endl;
		std::cout << sizeof(Base2) << std::endl;
		std::cout << sizeof(Son1) << std::endl;
		
		Base1* p1;
		Base2* p2;
		Son1 obj;

		p1 = &obj;
		p2 = &obj;

		p1->Fun1();

		p2->Fun2();

		/*
		
			0040125B  lea         eax,[ebp-28h]  
			0040125E  mov         dword ptr [ebp-0Ch],eax  

			00401261  lea         eax,[ebp-28h]  
			00401264  mov         dword ptr [ebp-10h],eax 

			00401267  mov         eax,dword ptr [ebp-0Ch]  
			0040126A  mov         edx,dword ptr [eax]  
			0040126C  mov         ecx,dword ptr [ebp-0Ch]  
			0040126F  mov         eax,dword ptr [edx]  
			00401271  call        eax  

			00401273  mov         eax,dword ptr [ebp-10h]  
			00401276  mov         edx,dword ptr [eax]  
			00401278  mov         ecx,dword ptr [ebp-10h]  
			0040127B  mov         eax,dword ptr [edx+4]  
			0040127E  call        eax  
		
		*/
	}

	return 0;
}

虚表(多)

#include <iostream>
#include <Windows.h>

class Base1
{
public:
	int m_A;

public:
	virtual void Fun1() {}
	virtual void Fun2() {}
};

class Base2
{
public:
	int m_B;

public:
	virtual void Fun3() {}
	virtual void Fun4() {}

};

class Son : public Base1, public Base2
{
public:
	int m_C;

public:
	virtual void Fun1() override {}
	virtual void Fun2() override {}
	virtual void Fun3() override {}
	virtual void Fun4() override {}
};

int main()
{
	// 对象模型
	std::cout << sizeof(Base1) << std::endl;
	std::cout << sizeof(Base2) << std::endl;
	std::cout << sizeof(Son) << std::endl;

	Son obj{};

	/*
	
		0x0019FED0  34 31 40 00  41@.
		0x0019FED4  00 00 00 00  ....

		0x0019FED8  40 31 40 00  @1@.
		0x0019FEDC  00 00 00 00  ....

		0x0019FEE0  00 00 00 00  ....
	
	*/

	return 0;
}

纯虚

#include <iostream>
#include <Windows.h>

class Base
{
public:
	virtual void Fun() = 0;
};

class Son : public Base
{
public:
	virtual void Fun() override {}
};

int main()
{
	Son obj;

	/*
	
		00401099  lea         ecx,[obj]  
		0040109C  call        Son::Son (0401020h)  
		
			00401029  mov         dword ptr [this],ecx
			0040102C  mov         ecx,dword ptr [this]
			0040102F  call        Base::Base (0401000h)

				00401009  mov         dword ptr [this],ecx
				0040100C  mov         eax,dword ptr [this]
				0040100F  mov         dword ptr [eax],offset Base::`vftable' (0403104h)

			00401034  mov         eax,dword ptr [this]
			00401037  mov         dword ptr [eax],offset Son::`vftable' (040310Ch)

	*/

	return 0;
}

相关文章:

  • 放大镜案例
  • 2025软件测试面试题200问(含答案+文档)
  • CSDN如何设置付费专栏
  • 微服务环境搭建架构介绍(附超清图解源代码)
  • 04-DevOps-安装并初始化Jenkins
  • Linux文件系统
  • 数字签名技术基础
  • 【MyBatis】#{} 与 ${} 的区别(常见面试题)
  • Vue.js 与 Ajax(Axios)的深入探索
  • 力扣——划分字母区间
  • 实验 Figma MCP + Cursor 联合工作流
  • (南京观海微电子)——码片与码元之间的关系
  • MATLAB中random函数用法
  • 功能全面的手机壁纸应用,种类齐全、众多高清壁纸
  • OpenHarmony包管理子系统
  • Linux lsblk 命令详解:查看磁盘和分区信息 (中英双语)
  • Spring Boot Validation 接口校验:从零到掌握
  • python中轻量级 LLM 应用开发框架 Promptic 如何有效进行对话管理?
  • AI革命下的多元生态:DeepSeek、ChatGPT、XAI、文心一言与通义千问的行业渗透与场景重构
  • 基于Hadoop的汽车大数据分析系统设计与实现【爬虫、数据预处理、MapReduce、echarts、Flask】
  • 国际足联女子世界杯再次扩军,2031年起增至48支球队
  • 国家发改委:美芯片药品等领域关税影响全球科技发展,损害人类共同利益
  • 虚假认定实质性重组、高估不良债权价值,原中国华融资产重庆分公司被罚180万元
  • 西安碑林博物馆票价将调至85元,工作人员:10元属于改扩建期间惠民票
  • 陈丹燕:赤龙含珠
  • 巴称击落多架印度“阵风”战机,专家:小规模冲突巴空军战力不落下风