MinHook
x86/x64 API Hook 库。它既支持X86的API Hook 也支持X64的API Hook(微软Detours支持x64的API Hook的版本死贵),项目中应用,目前没发现不稳定因素。
源码所在的Git库:https://github.com/RaMMicHaeL/minhook
源码结构:
HDE目录下为 HDE反汇编引擎的代码:HDE (Hancker Disassembler Engine)
hook.c / MinHook.h / trampoline.h / trampoline.c / buffer.h / buffer.c 构成了 MinHook的代码。
编译:
在MinHook下载的源码中,直接带有工程 VS2008,VS2010等,可以直接打开编译。
MinHook API简要说明:
MH_STATUS WINAPI MH_Initialize(VOID);
初始化MinHook库,必须在程序开始做一次初始化,否则无法使用它进行API Hook
MH_STATUS WINAPI MH_Uninitialize(VOID);
反初始化MinHook库,在程序结束之前调用,主要是用于释放申请的内存。
MH_STATUS WINAPI MH_CreateHook(LPVOID pTarget, LPVOID pDetour, LPVOID *ppOriginal);
创建Hook,pTarget指向目标函数或目标地址,pDetour指向自己的函数,ppOriginal指向Trampline,用于调用原函数
相当于创建了一个Hook Item,其中保存了进行Hook所需要的信息,原始Codes,Trampline信息等,并放到了MinHook的链表中。
此函数仅仅是创建了一个Hook,但是这个Hook是不生效的。
MH_STATUS WINAPI MH_RemoveHook(LPVOID pTarget);
移除Hook,pTarget是先前传递给MH_CreateHook函数的pTarget函数,此处的移除与CreateHook对应。
移除Hook时,先确认Hook已经Disable了,然后再删除Hook Item。如果没有Disable,则首先Disable掉。与MH_DisableHook无关
MH_STATUS WINAPI MH_EnableHook(LPVOID pTarget);
使得Hook生效,也即将JMP指令写到Target函数上,让其跳到我们设置的函数上。
MH_STATUS WINAPI MH_DisableHook(LPVOID pTarget);
使得Hook失效,也即将Target地址处原始的指令写回,注意此处并不删除我们用CreateHook创建的Hook Item。
MH_STATUS WINAPI MH_QueueEnableHook(LPVOID pTarget);
MH_STATUS WINAPI MH_QueueDisableHook(LPVOID pTarget);
MH_STATUS WINAPI MH_ApplyQueued(VOID);
这三个函数用于将MinHook的Hook Item列表中的多个Item设置为Queue Enable,调用一次MH_ApplyQueued()方法
可以让所有设置过的都生效。
示例:
#include <Windows.h> #include "MinHook.h" #pragma comment(lib, "libMinHook.x86.lib") static int (WINAPI * OLD_MessageBoxW)(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType) = MessageBoxW; static PVOID ppTrampline = NULL; int WINAPI New_MessageBoxW(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCation, UINT uType) { int ret = 0; if ( NULL != ppTrampline) { int ret = ((int (WINAPI * )(HWND, LPCWSTR, LPCWSTR, UINT))ppTrampline)( hWnd, L"输入的参数已修改", L"[测试]", uType); } return ret; } BOOL HOOK() { BOOL bRet = FALSE; do { if ( MH_OK != MH_CreateHook( OLD_MessageBoxW, New_MessageBoxW, &ppTrampline)) break; if ( MH_OK != MH_EnableHook(OLD_MessageBoxW)) break; bRet = TRUE; } while (FALSE); return bRet; } BOOL UnHook() { BOOL bRet = FALSE; do { if ( MH_OK != MH_RemoveHook(OLD_MessageBoxW)) break; bRet = TRUE; } while (FALSE); return bRet; } void main() { if( MH_OK != MH_Initialize()) // 初始化 { printf("Initialize MinHook Error!\n"); } ::MessageBoxW(NULL, L"正常消息框", L"测试", MB_OK); HOOK(); ::MessageBoxW(NULL, L"正常消息框", L"测试", MB_OK); UnHook(); MH_Uninitialize(); // 反初始化 return ; }
补充:
MHook也是一个API Hook库,也可以用于x64,x86两个平台的API Hook。
MHook与MinHook类似,MHook与MinHook用的都是反汇编引擎解析的指令,获取拷贝的指令长度。
据说MHook有一个隐形问题:处理不好Hook链,具体原因从代码没看出问题(功力不够),实例也没发现错误之处。有待验证