这里写目录标题
1 什么是Detours
detours是微软提供的一套函数库,主要用于win32 API的拦截。
2 准备工作(环境)
2.1 在环境变量中增加nmake.exe安装目录
我是Windows 64位系统,安装 Visual Studio 2022,安装在D盘。记住或找到VS的安装目录,默认安装的一般在C:\Program Files\Microsoft Visual Studio这个目录下,然后我们需要找到nmake.exe所在的位置。
我的nmake.exe文件位置:
D:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Tools\MSVC\14.40.33807\bin\Hostx64\x64\nmake.exe
把D:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Tools\MSVC\14.40.33807\bin\Hostx64\x64\这个目录增加到系统环境变量中,这样我们就可以在命令行使用namke了。
2.2 下载detours源码
下载detours的资源,地址:https://github.com/microsoft/detours
3 编译detours
3.1 使用nmake编译
下载到本地后解压至任意文件夹,打开文件夹,在文件地址栏输入cmd,打开cmd终端;
输入入nmake,此时出现fatal error C1034: windows.h: 不包括路径集(踩坑之一),我们需要设置VS命令行编译环境。
打开安装目录下的Build目录,我的位置是:
D:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build
如果要在32位系统下生成32位代码,就执行vcvars32
如果要在64位系统下生成64位代码,就执行vcvars64
如果要在64位系统下生成32位代码,就执行vcvarsall amd64_x86
如果要在32位系统下生成64位代码,就执行vcvarsall x86_amd64
因为我是64位系统,我要生成64位代码,因此直接将vcvars64.bat这个文件拖入cmd命令窗口中,运行完成后,我们再输入 nmake进行编译,编译结果如下:
成功之后就会增加Detours的lib、include、bin目录,我们可以看到Detours里面的src文件夹下面有detours.h与detours.cpp,在lib.x64文件夹下面有detours.lib,我们后续使用Detours就需要这几个文件。
3.2 在VS中直接编译
在解压目录下找到vc目录,里面有一个VS的工程,在VS中打开,我使用的是VS2022。
这里要记住,我的是64位系统,我可以选择生成32位或者64位代码,因此只能选择x86和x64这两种方式,否则编译过不去。
4 如何在vs2022中使用Detours
4.1 在工程配置中增加detours.h文件包含目录
不设置#include "detours.h"时找不到文件
4.2 在工程配置中增加库目录
不设置将出现
错误 LNK1104 无法打开文件“detours.lib”
5 下面是个简单的例子:
#include <stdio.h>
#include <windows.h>
#include "detours.h"
static VOID (WINAPI * TrueSleep)(DWORD dwMilliseconds) = Sleep; // 原函数
// 替代的函数
VOID WINAPI TimedSleep(DWORD dwMilliseconds)
{
TrueSleep(dwMilliseconds);
}
BOOL WINAPI DllMain(HINSTANCE hinst, DWORD dwReason, LPVOID reserved)
{
if (dwReason == DLL_PROCESS_ATTACH)
{
// 注册
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&(PVOID&)TrueSleep, TimedSleep);
DetourTransactionCommit();
}
else if (dwReason == DLL_PROCESS_DETACH)
{
// 卸载
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourDetach(&(PVOID&)TrueSleep, TimedSleep);
DetourTransactionCommit();
}
return TRUE;
}