MinHook是一个基于微软Detours技术的可移植Hook库,它允许开发者在运行时更改函数定义,而无需修改原始函数代码。以下是关于MinHook的详细介绍:
基本概念
定义:MinHook使用内存污染和跳转技术来实现Hook,使得开发者能够在不修改源代码的情况下,拦截并修改系统或应用程序的特定函数调用。
用途:MinHook在调试、测试、性能监控、安全应用以及扩展应用程序功能等方面具有广泛应用。
关键技术特点
钩子创建:通过MH_CreateHookApi等辅助函数,可以轻松创建对目标API的钩子。
线程安全:库中的钩子管理功能考虑了多线程环境,确保在并发情况下正确地启用或禁用钩子。
内存管理优化:经过重写后的C版本显著减少了内存占用和管理开销。
兼容性:支持从Visual Studio 2015到2017的各种版本,以及MinGW编译器。
应用场景
调试与测试:通过钩子函数记录调用参数,检查程序运行状态,甚至模拟异常情况。
性能监控:实时测量特定API的执行时间,找出性能瓶颈。
安全应用:阻止恶意行为,检测病毒或rootkit。
插件系统:插入自定义逻辑,扩展应用程序功能。
样例
这里以MessageBoxW
为例,首先声明要HOOK的函数指针:
typedef int (WINAPI* MESSAGEBOXW)(HWND, LPCWSTR, LPCWSTR, UINT);
定义函数指针变量,这个指针将会指向原始的API调用
MESSAGEBOXW fpMessageBoxW = NULL;
定义hook后的函数(也就是在调用MessageBoxW时,不会再调用原始函数,而是调用我们定义的函数)
这里我们在hook的函数里还是调用原始函数,但是将消息框内容改成了"Hooked"
// Detour function which overrides MessageBoxW.
int WINAPI DetourMessageBoxW(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType)
{
return fpMessageBoxW(hWnd, L"Hooked!", lpCaption, uType);
}
初始化minHook
if (MH_Initialize() != MH_OK)
{
return 1;
}
创建apihook(创建好后处理禁用的状态,需要启用才能生效)
// Create a hook for MessageBoxW, in disabled state.
if (MH_CreateHookEx(&MessageBoxW, &DetourMessageBoxW, &fpMessageBoxW) != MH_OK)
{
return 1;
}
启用apihook
// Enable the hook for MessageBoxW.
if (MH_EnableHook(&MessageBoxW) != MH_OK)
{
return 1;
}
使用完成后,禁用apihook,并卸载minHook
// Disable the hook for MessageBoxW.
if (MH_DisableHook(&MessageBoxW) != MH_OK)
{
return 1;
}
// Expected to tell "Not hooked...".
MessageBoxW(NULL, L"Not hooked...", L"MinHook Sample", MB_OK);
// Uninitialize MinHook.
if (MH_Uninitialize() != MH_OK)
{
return 1;
}
完整代码:
#include <iostream>
#include "minHook/MinHook.h"
template <typename T>
inline MH_STATUS MH_CreateHookEx(LPVOID pTarget, LPVOID pDetour, T** ppOriginal)
{
return MH_CreateHook(pTarget, pDetour, reinterpret_cast<LPVOID*>(ppOriginal));
}
template <typename T>
inline MH_STATUS MH_CreateHookApiEx(
LPCWSTR pszModule, LPCSTR pszProcName, LPVOID pDetour, T** ppOriginal)
{
return MH_CreateHookApi(
pszModule, pszProcName, pDetour, reinterpret_cast<LPVOID*>(ppOriginal));
}
typedef int (WINAPI* MESSAGEBOXW)(HWND, LPCWSTR, LPCWSTR, UINT);
// Pointer for calling original MessageBoxW.
MESSAGEBOXW fpMessageBoxW = NULL;
// Detour function which overrides MessageBoxW.
int WINAPI DetourMessageBoxW(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType)
{
return fpMessageBoxW(hWnd, L"Hooked!", lpCaption, uType);
}
int main()
{
// Initialize MinHook.
if (MH_Initialize() != MH_OK)
{
return 1;
}
// Create a hook for MessageBoxW, in disabled state.
if (MH_CreateHookEx(&MessageBoxW, &DetourMessageBoxW, &fpMessageBoxW) != MH_OK)
{
return 1;
}
// or you can use the new helper function like this.
//if (MH_CreateHookApiEx(
// L"user32", "MessageBoxW", &DetourMessageBoxW, &fpMessageBoxW) != MH_OK)
//{
// return 1;
//}
// Enable the hook for MessageBoxW.
if (MH_EnableHook(&MessageBoxW) != MH_OK)
{
return 1;
}
// Expected to tell "Hooked!".
MessageBoxW(NULL, L"Not hooked...", L"MinHook Sample", MB_OK);
// Disable the hook for MessageBoxW.
if (MH_DisableHook(&MessageBoxW) != MH_OK)
{
return 1;
}
// Expected to tell "Not hooked...".
MessageBoxW(NULL, L"Not hooked...", L"MinHook Sample", MB_OK);
// Uninitialize MinHook.
if (MH_Uninitialize() != MH_OK)
{
return 1;
}
return 0;
}
相关资料
https://github.com/TsudaKageyu/minhook
https://www.codeproject.com/Articles/44326/MinHook-The-Minimalistic-x-x-API-Hooking-Libra
https://www.cnblogs.com/zhaotianff/p/18073138