虚函数Hook代码

作为备记,直接上代码.

#include <windows.h>

//更改地址跳转表
long ExChangeJumpTable(void* vfptr,int index,void* Value){
	//虚表函数地址
	void * functionJmpAddr = ((void**)vfptr)[index];
	//E9 xx xx xx xx
	unsigned char *codeAddr = (unsigned char*)functionJmpAddr;
	//检查跳转代码
	if(*codeAddr == 0xE9 || *codeAddr == 0xEB)
	{
		//32位和64位均为4字节
		int *jmpValue = (int*)(codeAddr+1);
		//跳转数
		int jmpDistance = *jmpValue;
		//真实地址计算公式:当前代码地址 + 跳转距离 + 代码长度
		long dRet = (long)codeAddr + jmpDistance + 5;

		DWORD oldPro = 0;
		BOOL bRet = VirtualProtect(jmpValue,sizeof(int),PAGE_EXECUTE_READWRITE,&oldPro);
		*jmpValue = (int)((unsigned char*)Value - codeAddr) - 5;
		VirtualProtect(jmpValue,sizeof(int),oldPro,NULL);

		return dRet;
	}
	else if(*codeAddr == 0xEA)
	{
		//跳转代码
		long *jmpValue = (long*)(codeAddr+1);
		//跳转数
		long jmpAddr = *jmpValue;

		DWORD oldPro = 0;
		BOOL bRet = VirtualProtect(jmpValue,sizeof(long),PAGE_EXECUTE_READWRITE,&oldPro);
		*jmpValue = (long)Value;
		VirtualProtect(jmpValue,sizeof(long),oldPro,NULL);

		return jmpAddr;
	}
	else
	{
		return -1;
	}
}

//更改虚表地址
DWORD ExChangeVirtualTable(void* vfptr,int index,void* Value)
{
	DWORD oldPro = 0;
	BOOL bRet = VirtualProtect(vfptr,sizeof(void*)*(index+1),PAGE_EXECUTE_READWRITE,&oldPro);
	void * func = ((void**)vfptr)[index];
	((void**)vfptr)[index] = Value;
	VirtualProtect(vfptr,sizeof(void*)*(index+1),oldPro,NULL);
	return (DWORD)func;
}

class A{
public:
	virtual void PutString(const char* value){
		printf("A::this:0x%08x\n",this);
		printf("Class:A::(%s) %d\n",value,m_nValue);
	}
	int m_nValue;
};

class C:public A
{ 
public:
	virtual void PutString(const char* value)
	{
		printf("C::this:0x%08x\n",this);
		printf("Class:C::(%s) %d\n",value,m_nValue);
	}
};

class D{
public:
	virtual void DDD(const char *value){
		printf("D::this:0x%08x\n",this);
		printf("D:DDD:%s\n",value);
	}
};

#ifndef _WIN64
#define VFPTR_FunctionCall(A,func)	\
	__asm		\
	{			\
		mov ecx,A	\
	}				\
	func;			\

#endif

//使用C方法调用虚函数
void VFPTR_Test(){
	A a;
	a.m_nValue = 100;
	A * pa= &a; 
	
	printf("this:0x%08x\n",pa);

	void *pthis=&a;
	void **__vfptr = *(void***)pthis;
	void * func = __vfptr[0];
	typedef void (__stdcall *PPutString)(const char* value);
	PPutString ps = (PPutString)func;
#ifndef _WIN64
	VFPTR_FunctionCall(pa,ps("444"));
#endif
}

//交换同类虚函数地址
void VirtualTable_Test()
{
	A a;
	C c;
	a.m_nValue = 100;
	c.m_nValue = 200;
	A *pa= &c;
	
	unsigned int* pthis= (unsigned int*)pa;
	void **__vfptr_c = *(void***)pthis;
	void * func = __vfptr_c[0];

	pa = &a;
	pthis= (unsigned int*)pa;
	void **__vfptr_a = *(void***)pthis;
	func = __vfptr_a[0];

	DWORD oldPro = 0;
	BOOL bRet = VirtualProtect(__vfptr_a,4,PAGE_EXECUTE_READWRITE,&oldPro);
	__vfptr_a[0] = __vfptr_c[0];
	VirtualProtect(__vfptr_a,4,oldPro,NULL);
	pa = &a;
	pa->PutString("aaaa");

	bRet = VirtualProtect(__vfptr_c,4,PAGE_EXECUTE_READWRITE,&oldPro);
	__vfptr_c[0] = func;
	VirtualProtect(__vfptr_c,4,oldPro,NULL);

	pa = &c;
	pa->PutString("cccc");
}

//更改虚函数调用表地址
void JmpTable_Test(){
	C c;
	c.m_nValue = 200;
	A *pa= &c;

	D d;
	D * pd = &d;

	unsigned int* pthis= (unsigned int*)pa;
	void **__vfptr_c = *(void***)pthis;
	void * func = __vfptr_c[0];

	pthis= (unsigned int*)pd;
	void **__vfptr_d = *(void***)pthis;
	func = __vfptr_d[0];

	//更改虚表,只能针对指针处理
	/*DWORD oldPro = 0;
	BOOL bRet = VirtualProtect(__vfptr_c,4,PAGE_EXECUTE_READWRITE,&oldPro);
	__vfptr_c[0] = __vfptr_d[0];
	VirtualProtect(__vfptr_c,4,oldPro,NULL);*/
	//ExChangeVirtualTable(__vfptr_c,0,func);

	//更改跳转表法,万能HOOK
	ExChangeJumpTable(__vfptr_c,0,func);

	c.PutString("cccc");
	pa->PutString("dddd");
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值