HOOK虚函数

声明

首先呢,这里会牵扯到虚函数,建议先看看以下博客(前三章就行),
c++类成员函数指针
详解虚函数的实现过程之初探虚表(1)
详解虚函数的实现过程之单继承(2)
详解虚函数的实现过程之多重继承(3)
详解虚函数的实现过程之虚基类(4)
详解虚函数的实现过程之菱形继承(5)

看了之后大家会了解到:虚函数的地址存放在虚表里面,虚表地址放在对象里面,虚表地址都是放在对象的前四个字节。

所以我们可以进行把存放在 虚表里面这个函数地址值给替换(这也就是Hook手法之一)了,当进行调用虚函数时,是不是就可以改变程序的走向,和原来不同。

过程

class Base
{
public:
	virtual void Print() {
		printf("这是一个虚函数");
	}
};

void	Myprint() {

	printf("这是一个普通函数");

}

过程综述

Base类里面有个虚函数,虚表地址存放在对象的前四个字节里面,然后虚函数地址存放在虚表的前四个字节里面,
Myprint函数地址,把虚表里面前四个字节的地址值给替换了,这样就Hook成功。

代码讲解

  1. 创建一个Base对象,然后用指针指向它
	Base pb;
	Base* Pb = &pb;

或者这样也行

Base* Pb = new Base();
  1. 找到虚表中存放虚函数的地址的地址单元
DWORD* pVtAddr = (DWORD*)*(DWORD*)Pb;

首先,把这个指针的范围放在四个字节,因为虚表地址就四个字节,所以有了(DWORD *),然后出内容,加个*号,即*(DWORD *),取出内容后,内容也就是虚表的地址值,此时这个指针也就指向了这个地址值,范围是整个虚表,然后还要强转一下范围(DWORD*)(因为函数的地址值是前4个字节),所以就有了(DWORD*)*(DWORD*)Pb

  1. 修改一下这个地址单元的属性(原来是不可写的,改为可写)
DWORD	dwOldProtect = 0;
VirtualProtect(pVtAddr, 4, PAGE_READWRITE, &dwOldProtect);
  1. 然后用函数地址值来覆盖虚表中存放虚函数的地址地址单元
*pVtAddr = (DWORD)Myprint;
  1. 调用函数
Pb->Print();
  1. 如果利用Base* Pb = new Base();出来的堆空间,别忘了把它delete掉
delete	Pb;

正常代码:

#include <iostream>
#include<Windows.h>
class Base
{
public:
	virtual void Print() {
		printf("这是一个虚函数");
	}
};

void	Myprint() {

	printf("这是一个普通函数");

}
int main()
{
	Base* Pb = new Base();

	Pb->Print();
	
	delete	Pb;
	return	0;
}

在这里插入图片描述

Hook后:

#include <iostream>
#include<Windows.h>
class Base
{
public:
	virtual void Print() {
		printf("这是一个虚函数");
	}


};

void	Myprint() {

	printf("这是一个普通函数");

}
int main()
{
	Base* Pb = new Base();

	DWORD* pVtAddr = (DWORD*)*(DWORD*)Pb;

	DWORD	dwOldProtect = 0;
	
	VirtualProtect(pVtAddr, 4, PAGE_READWRITE, &dwOldProtect);
	
	*pVtAddr = (DWORD)Myprint;
	
	Pb->Print();
	
	delete	Pb;
	return	0;



}

在这里插入图片描述

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

寻梦&之璐

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值