Process Hacker源码中的用户态hook的做法

processhacker-code-5632\1.x\trunk\NProcessHacker\hook.h

typedef struct _PH_HOOK
{
    PVOID Function;
    PVOID Target;
    BOOLEAN Hooked;
    CHAR Bytes[5];
} PH_HOOK, *PPH_HOOK;

这个结构体用来保存每个Hook的信息,Function是hook点的地址, Target是Trampoline的地址,Bytes用来备份Function点处原来的5个字节。

processhacker-code-5632\1.x\trunk\NProcessHacker\hook.c

VOID PHAPI PhInitializeHook(
    PPH_HOOK Hook,
    PVOID Function,
    PVOID Target
    )
{
    memset(Hook, 0, sizeof(PH_HOOK));
    Hook->Function = Function;
    Hook->Target = Target;
}

初始化Hook结构体,指定hook点与Trampoline的地址。

NTSTATUS PHAPI PhHook(
    PPH_HOOK Hook
    )
{
    NTSTATUS status = STATUS_SUCCESS;
    ULONG oldProtection;
    PCHAR function;

    /* Change the page protection of the target page so we can write to it. */
    if (!VirtualProtect(Hook->Function, 5, PAGE_EXECUTE_READWRITE, &oldProtection))
        return STATUS_ACCESS_VIOLATION;

    __try
    {
        function = (PCHAR)Hook->Function;
        /* Copy the original five bytes for unhooking. */
        memcpy(Hook->Bytes, function, 5);
        /* Hook the function by writing a jump instruction. */
        Hook->Hooked = TRUE;
        /* jmp Target */
        *function = 0xe9;
        *(PULONG_PTR)(function + 1) = (ULONG_PTR)Hook->Target - (ULONG_PTR)Hook->Function - 5;
    }
    __except (EXCEPTION_EXECUTE_HANDLER)
    {
        status = GetExceptionCode();
    }

    /* Restore the old page protection. */
    VirtualProtect(Hook->Function, 5, oldProtection, NULL);

    return status;
}

用于完成对Hook点的5个字节的替换,替换成e9 XXXXXXXX[Trampoline与Hook点之间的偏移距离]。

NTSTATUS PHAPI PhUnhook(
    PPH_HOOK Hook
    )
{
    NTSTATUS status = STATUS_SUCCESS;
    ULONG oldProtection;

    /* Change the page protection of the target page so we can write to it. */
    if (!VirtualProtect(Hook->Function, 5, PAGE_EXECUTE_READWRITE, &oldProtection))
        return STATUS_ACCESS_VIOLATION;

    __try
    {
        /* Unpatch the function by restoring the original first 5 bytes. */
        memcpy(Hook->Function, Hook->Bytes, 5);
        Hook->Hooked = FALSE;
    }
    __except (EXCEPTION_EXECUTE_HANDLER)
    {
        status = GetExceptionCode();
    }

    /* Restore the old page protection. */
    VirtualProtect(Hook->Function, 5, oldProtection, NULL);

    return status;
}

Unhook的过程恰好相反,用备份的5个字节恢复Hook点。

posted @ 2014-06-11 13:33  Daniel King  阅读(623)  评论(0编辑  收藏  举报