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;
}

基于minhook的Windows HOOK_应用程序

相关资料

https://github.com/TsudaKageyu/minhookhttps://www.codeproject.com/Articles/44326/MinHook-The-Minimalistic-x-x-API-Hooking-Libra