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

news/2025/2/23 22:25:02
  • 公开视频 -> 链接点击跳转公开课程
  • 博客首页 -> ​​​链接点击跳转博客主页

Contents">目录

C%AC%E7%89%B9%E6%80%A7-toc" name="tableOfContents" style="margin-left:40px">基本特性

Contents" style="margin-left:40px">构造函数

Contents" style="margin-left:40px">静态成员

Contents" style="margin-left:40px">常量成员

Contents" style="margin-left:40px">继承构造

Contents" style="margin-left:40px">继承(单)

Contents" style="margin-left:40px">继承(多)

Contents" style="margin-left:40px">继承(菱)

Contents" style="margin-left:40px">多态(单)

Contents" style="margin-left:40px">多态(多)

Contents" style="margin-left:40px">虚表(单)

Contents" style="margin-left:40px">虚表(多)

Contents" style="margin-left:40px">纯虚


Contents" />

C%AC%E7%89%B9%E6%80%A7" name="%E5%9F%BA%E6%9C%AC%E7%89%B9%E6%80%A7">基本特性

#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;
}


http://www.niftyadmin.cn/n/5863824.html

相关文章

红队内网攻防渗透:内网渗透之内网对抗:实战项目VPC1打靶PHP-RCE三层代理路由防火墙上线密码喷射域控提权

红队内网攻防渗透 实战网络攻防靶场记录1.靶机配置详情讲解1.1 入口点靶机:Windows Server 20121.2 第一层靶机:Windows 7 + Windows 101.3 第二层靶机:Windows 2012 R21.4 第三层靶机:Windows 2016 web +Windows 2016 AD域1.5 攻击者系统 :Kali-linux2.靶场渗透完整流程2…

算法-栈和队列篇04-滑动窗口最大值

滑动窗口最大值 力扣题目链接 题目描述 给你一个整数数组 nums&#xff0c;有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。 返回 滑动窗口中的最大值 。 解题思路 这道题目一开始我是直…

Orcale、MySQL中参数类型的详解和运用场景(带示例)

Oracle 中的参数类型及运用场景 1. 数值类型 NUMBER(p, s) 详解&#xff1a;p 表示精度&#xff08;即数字的总位数&#xff09;&#xff0c;s 表示小数位数。例如&#xff0c;NUMBER(5, 2) 可以存储最大为 999.99 的数字。运用场景&#xff1a;适用于需要精确计算的财务数据…

docker基操

docker基操 首先就是安装docker使用docker:创建容器-制作一个镜像-加载镜像首先就是安装docker 随便找一个教程安装就可以,安装过程中主要是不能访问谷歌,下面这篇文章写了镜像的一些问题: 安装docker的网络问题 使用docker:创建容器-制作一个镜像-加载镜像 主要是参考:这篇…

【数字图像处理二】图像增强与空域处理

1. 图像增强的目的 图像增强的目的是通过各种处理方法改善图像的视觉效果&#xff0c;旨在满足特定应用场合的需求。其核心目的是增强图像的整体或局部特性。通过图像增强&#xff0c;我们能够将原本模糊的图像变得更加清晰&#xff0c;突出某些感兴趣的特征&#xff0c;扩大图…

一个解析cyber record文件的python示例脚本

Cyber RT 是百度开源的一个高性能、灵活的机器人操作系统&#xff0c;cyber record 是 Cyber RT 中用于录制和回放数据的工具。下面是一个使用 Python 解析 cyber record 文件的示例&#xff0c;该示例使用 cyber_py 库&#xff08;Cyber RT 的 Python 绑定&#xff09;来读取记…

迎接2025,立个flag

2025计划书 博客更新时间 每周二、周四、周天晚上20&#xff1a;00-23:00间进行更新 博客内容粗略版规划 1、 大模型相关论文分享&#xff08;数据标注、COT、prompt等方向&#xff09; 2、强化学习数学理论&#xff08;内容偏数学&#xff0c;故周天晚上更新&#xff09; 3、…

Python常见面试题的详解17

1. 说明HTTP 和 HTTPS的区别 安全性&#xff1a;HTTP 是明文传输协议&#xff0c;这意味着在数据传输过程中&#xff0c;信息就像在 “裸奔”&#xff0c;容易被窃取和篡改&#xff0c;安全性堪忧。而 HTTPS 是在 HTTP 基础上加入了 SSL/TLS 协议&#xff0c;通过加密和身份验证…