微软Detours Hook库编译与使用
Detours 是微软开发的一个强大的Windows API钩子库,用于监视和拦截函数调用。它广泛应用于微软产品团队和众多独立软件开发中,旨在无需修改原始代码的情况下实现函数拦截和修改。Detours 在调试、监控、日志记录和性能分析等方面表现出色,已成为开发者的重要工具。本章将指导读者编译并使用Detours库,通过实现一个简单的弹窗替换功能,帮助读者熟悉该库的使用技巧。
Detours 是一个兼容多个Windows系列操作系统版本(包括 Windows XP 到 Windows 11)的工具库。它现在在 MIT 开源许可证下发布,简化了开发者的使用许可流程,并允许社区利用开源工具和流程来支持其发展,目前该库的稳定版本为4.0.1读者可通过如下官方链接自行下载到本地。
- Detours 4.0.1:https://github.com/microsoft/Detours/releases
下载文件后打开目录,其中src目录下存储的是Detours库的源代码,而samples则是一些使用案例,当准备就绪后读者需要打开Visual Studio开发者命令提示符,你可以从开始菜单中找到Visual Studio Tools工具菜单,并在其中找到VS20XX x86 本机工具命令提示或Developer Command Prompt for VS 20XX字样,此处以x86为例,在命令提示符中跳转到Detours源代码目录,运行 nmake 命令执行编译。

如果一切顺利,这将会编译Detours库并生成所需的二进制文件,其中include保存有头文件信息,而lib.X86则包含有detours.lib库文件,如下图中所示。

接着我们打开Visual Studio工具,新建一个可执行控制台项目并配置包含引用目录及库目录,如下图所示;

接着我们来实现拦截并替换弹窗功能,在Windows中弹窗接口为MessageBoxW函数,首先需要定义OriginalMessageBoxW的函数指针,该指针用于指向原始的MessageBoxW函数地址。接着定义CustomMessageBoxW函数,在函数内首先将弹窗提示替换为自定义内容,并携带该参数调用OriginalMessageBoxW原函数地址,以此来实现替代弹窗功能。
|
接着就是对挂钩与摘钩的函数封装,分别定义这两个函数,其中InstallHook 函数通过Detours事务的方式,将原始的 MessageBoxW 函数指针替换为自定义的 CustomMessageBoxW 函数指针,从而拦截并修改该函数的行为。相反,RemoveHook 函数则通过类似的事务机制,将自定义的 CustomMessageBoxW 函数指针替换回原始的 MessageBoxW 函数指针,以恢复函数的原始行为。
// 安装钩子 |
在程序入口处,我们分三次调用MessageBoxW函数,其中第一次调用及最后依次调用均在未挂钩状态下进行,第二次调用之前通过InstallHook()安装钩子,之后再调用MessageBoxW函数,并在调用结束后通过RemoveHook()移除钩子,编译这段代码。
int main(int argc, char *argv[]) |
使用x64dbg调试器加载运行代码,并寻找到程序的入口处,由于此处的入口处仅仅是一个main(int argc, char *argv[])所以,在汇编中我们可以直接寻找三个参数的关键变量位置,找到后即可定位到入口处,此时直接跟进去就可以看到主函数代码;

如下图中所示,当0x00321314处被执行后则钩子生效,当钩子生效后则底部0x00321347处的地址将被替换为自定义钩子地址,此时在其之上的入栈操作数将会失效;

继续跟进0x00321347这个地址,如下图所示该地址中的入口处已被替换为我们自定义的弹窗位置,此处是一个jmp无条件跳转,预示着将要转向。

我们继续跟进这个转向地址,则可看到如下图所示的反汇编指令集,这里的代码重新入栈了新的字符串变量,并在入栈后调用了原始MessageBoxW函数,并依次来实现替换函数弹窗中的内容。

此时,当继续调用原始函数时,虽函数中的提示信息为hello world但由于挂钩生效了则提示信息会被变更为hello lyshark,以此来实现对函数功能的替换与更正。

在实际应用中,我们通常通过 DLL 注入的方式使用 Detours 库,以便更好地实现对第三方程序的功能替换或修改,例如改变弹窗提示。这种方法能够更高效地应用 Hook 技术,实现对目标程序行为的控制和定制。
例如如下所示的这段代码,当使用注入器将其注入到第三方进程中时,首先DLL_PROCESS_ATTACH将被执行也就是开始挂钩,在挂钩函数中通过DetourFindFunction寻找到MessageBoxW函数的入口地址,并将其存储到OriginalMessageBoxW指针中,并通过DetourAttach对其进行挂钩。
|
当挂钩成功后则进程中任何调用弹窗的提示信息都将被替换成hello lyshark提示,而标题栏因未被替换则依然会保持原始状态,如下图是注入之前与注入之后的提示变化;

至此本章内容结束,其实Hook在安全领域的应用相当广泛,例如可以监控和拦截指定的API调用,检测分析程序的行为,拦截网络通信函数,监控数据传输,拦截文件操作和注册表访问等等,本文也只是抛砖引玉让读者能认识Detours库。更多有用的案例可自行参考samples目录下的内容学习。