首页 > 代码库 > Process Hacker源码中的用户态hook的做法

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

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

?
1
2
3
4
5
6
7
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

?
1
2
3
4
5
6
7
8
9
10
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的地址。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
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点之间的偏移距离]。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
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点。