MinHook源码阅读

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链,具体原因从代码没看出问题(功力不够),实例也没发现错误之处。有待验证

你可能感兴趣的:(MinHook源码阅读)