hook虚表监控虚表

RTTI(Runtime Type Identification,运行时类型识别)由c++编译器将对象的类型信息嵌入程序的只读数据段,以 支持C++的各种操作符在运行时确定(typeid)和检查(dynamic_cast)一个对象的数据类型。
对微软的编译器而言,RTTI和虚表位置在-4的地址构建。

#include <stdio.h>
#include <Windows.h>
#define VTSIZE	6
#pragma pack(1)
class Parent
{
public:
	virtual void Fun1() = 0;
	virtual void Fun2() = 0;
	virtual void Fun3() = 0;
	virtual void Fun4() = 0;
	virtual void Fun5() = 0;
};

class Child: public Parent
{
public:
	void Fun1()
	{
		printf("11111\n");
	}
	void Fun2()
	{
		printf("22222\n");
	}
	void Fun3()
	{
		printf("33333\n");
	}
	void Fun4()
	{
		printf("44444\n");
	}
	void Fun5()
	{
		printf("55555\n");
	}

};

typedef struct _JMP_TABLE_ITEM{
	//UCHAR uPushesi;	//backup esi for checkesp	push esi, pop esi

	UCHAR uMoveEaxForFactAddr;
	DWORD dwFactAddr;
	UCHAR uPashEaxForFactAddr;
	//UCHAR uPushad;	//0x60
	//UCHAR uPushfd;	//0x9c
	//UCHAR uJmp;
	//DWORD dwCheckAddr;
	//jmp to check function

	//simulate messagebox	exist issue
#ifdef DEBUG
	UCHAR push0;
	UCHAR zero0;
	UCHAR push1;
	UCHAR zero1;
	UCHAR push2;
	UCHAR zero2;
	UCHAR push3;
	UCHAR zero3;
	UCHAR tempmoveax;
	DWORD dwmsgAddr;
	UCHAR uJmpmsg;	//FF
	DWORD uJmpeaxaddr;	
	UCHAR add;
	UCHAR esp;
	UCHAR four;
#endif

	//UCHAR uPopad;	//61
	//UCHAR uPopfd;	//9d
	UCHAR uPopeax; //58
	UCHAR uJmp22;	//FF
	UCHAR uJmpEax;	//EO
	
}JMP_TABLE_ITEM;

void CheckFunc(DWORD checkNum)
{
	
}

void InitFakeVirtualTable(DWORD *pfakevt,JMP_TABLE_ITEM *pJMPTable, DWORD pFactvt, DWORD msgaddr)
{
	DWORD *pvt = (DWORD*)*(DWORD*)pFactvt;
	for(int i = 0; i < VTSIZE; ++i)
	{
		*pfakevt = (DWORD)pJMPTable;
		pJMPTable->uMoveEaxForFactAddr = 0xB8;
		pJMPTable->dwFactAddr = *(DWORD*)(pvt+i);
		pJMPTable->uPashEaxForFactAddr = 0x50;	//push fact virtual function address
		//pJMPTable->uPushad = 0x60;
		//pJMPTable->uPushfd = 0x9C;
		//pJMPTable->uJmp = 0xE9;
		//pJMPTable->dwCheckAddr = (DWORD)CheckFunc;
#ifdef DEBUG
		pJMPTable->push0 = 0x6A;
		pJMPTable->zero0 = 0x0;
		pJMPTable->push1 = 0x6A;
		pJMPTable->zero1 = 0x0;
		pJMPTable->push2 = 0x6A;
		pJMPTable->zero2 = 0x0;
		pJMPTable->push3 = 0x6A;
		pJMPTable->zero3 = 0x0;
		pJMPTable->tempmoveax = 0xB8;
		pJMPTable->dwmsgAddr = msgaddr;
		pJMPTable->uJmpmsg = 0xFF;	//FF
		pJMPTable->uJmpeaxaddr = 0xE0;
		pJMPTable->add = 0x83;
		pJMPTable->esp = 0xC4; 
		pJMPTable->four = 0x10;
#endif
		//pJMPTable->uPopad = 0x61;
		//pJMPTable->uPopfd = 0x9d;
		pJMPTable->uPopeax = 0x58;
		pJMPTable->uJmp22 = 0xFF;
		pJMPTable->uJmpEax = 0xE0;
		pfakevt++;pJMPTable++;
	}
}

void main()
{
	//Fake virtual table
	DWORD *pfakeVirtualTable = new DWORD[VTSIZE]();
	JMP_TABLE_ITEM *pJMPTable = new JMP_TABLE_ITEM[VTSIZE]();
	DWORD oldprotect = 0;
	VirtualProtect(pfakeVirtualTable,1024,PAGE_EXECUTE_READWRITE,&oldprotect);
	//VirtualProtect(pJMPTable,1024,PAGE_EXECUTE_READWRITE,&oldprotect);

	Parent *pChild = new Child();
	DWORD ptemp = (DWORD)pChild;
	
	//simulate checkfunc
	HMODULE hNtdll = GetModuleHandleA("user32.dll");
	DWORD addr = (DWORD)GetProcAddress(hNtdll,"MessageBoxA");

	InitFakeVirtualTable(pfakeVirtualTable,pJMPTable,ptemp,addr);

	*(DWORD*)pChild = (DWORD)pfakeVirtualTable;
	pChild->Fun1();
	pChild->Fun2();
	pChild->Fun3();
	pChild->Fun4();
	pChild->Fun5();
	VirtualProtect(pfakeVirtualTable,1024,oldprotect,&oldprotect);
	//VirtualProtect(pJMPTable,1024,oldprotect,&oldprotect);
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值