Detours使用方法,简单明了

什么是Detours

detours是微软提供的一套工具,主要用于win32 API的拦截。

准备工作(环境)

首先下载detours的资源,地址:https://github.com/microsoft/detours

  • 下载到本地后解压至任意文件夹;
  • 打开cmd终端进到这个文件夹下,键入nmake;
  • 编译完成后:image.png
  • 新建一个工程,将include中的detours.h移动至工程文件下;
  • 将lib.X64(X86也有对应目录)下的detours.lib移动至工程文件下;

我们的样例是拦截GetLocalTime这一获取本地时间的API,然后将时间的分修改为52。

示例代码:

#include <iostream>
#include <Windows.h>
//包含Detour的头文件和库文件
#include "detours.h"
#pragma comment (lib,"detours.lib")
using namespace std;

//保存函数原型(用指针存储要拦截的API)
void (*OldGetLocalTime)(LPSYSTEMTIME) = GetLocalTime;

//拦截后要执行的操作(这里是将时间的分改为52)
void NewGetLocalTime(LPSYSTEMTIME lpSystemTime) {
	OldGetLocalTime(lpSystemTime);
	lpSystemTime->wMinute = 52;
}

//下钩子函数
void StartHook() {
	//开始事务
	DetourTransactionBegin();
	//更新线程信息
	DetourUpdateThread(GetCurrentThread());
	//将拦截的函数附加到原函数的地址上
	DetourAttach(&(PVOID&)OldGetLocalTime, NewGetLocalTime);
	//结束事务
	DetourTransactionCommit();
}

//撤钩子函数
void EndHook() {
	//开始detours事务
	DetourTransactionBegin();
	//更新线程信息 
	DetourUpdateThread(GetCurrentThread());
	//将拦截的函数从原函数的地址上解除
	DetourDetach(&(PVOID&)OldGetLocalTime, NewGetLocalTime);
	//结束detours事务
	DetourTransactionCommit();
}

int main()
{
	//获取本地时间
	SYSTEMTIME time, time2;
	GetLocalTime(&time);
	cout << time.wHour << ":" << time.wMinute << endl;
	//下钩子
	StartHook();

	//下钩子后再次获取本地时间
	GetLocalTime(&time2);
	cout << time2.wHour << ":" << time2.wMinute << endl;

	//撤钩子
	EndHook();
	return 0;
}

运行结果

image.png
可以看到确实成功拦截了GetLocalTime这个win32 API。

补充

其实detours也可以拦截C/C++的库函数:

我们用stdlib.h中system函数来测试,原本的语句system(“notepad”)可以打开记事本程序,我们用detours拦截,并改为打开资源管理器。

注意:记得将工程改为release模式,因为debug模式下函数会被编译器劫持。

代码:

#include <iostream>
#include <Windows.h>
//包含Detour的头文件和库文件
#include "detours.h"
#pragma comment (lib,"detours.lib")
using namespace std;

//保存函数原型
int (*Oldsystem)(char const*) = system;

//拦截后的函数
void Newsystem(char const* command) {
	Oldsystem("explorer");
}

//下钩子函数
void StartHook() {
	//开始事务
	DetourTransactionBegin();
	//更新线程信息
	DetourUpdateThread(GetCurrentThread());
	//将拦截的函数附加到原函数的地址上
	DetourAttach(&(PVOID&)Oldsystem, Newsystem);
	//结束事务
	DetourTransactionCommit();
}

//撤钩子函数
void EndHook() {
	//开始事务
	DetourTransactionBegin();
	//更新线程信息 
	DetourUpdateThread(GetCurrentThread());
	//将拦截的函数从原函数的地址上解除
	DetourDetach(&(PVOID&)Oldsystem, Newsystem);
	//结束事务
	DetourTransactionCommit();
}

int main()
{
	//下钩子
	StartHook();

	system("notepad");

	//撤钩子
	EndHook();
	return 0;
}

运行结果:
image.png同样拦截成功。

欢迎讨论和指正。

  • 5
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值