-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathhook.c
121 lines (88 loc) · 2.52 KB
/
hook.c
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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
#include "hook.h"
#define kmalloc(_s) ExAllocatePoolWithTag(NonPagedPool, _s, 'SYSW')
#define kfree(_p) ExFreePool(_p)
LDE_DISASM lde_disasm;
BOOLEAN lde_init()
{
lde_disasm = (LDE_DISASM)ExAllocatePoolWithTag(NonPagedPool, 12800, 'oniZ');
if (lde_disasm)
{
RtlCopyMemory(lde_disasm, szShellCode, 12800);
return TRUE;
}
return FALSE;
}
KIRQL WPOFFx64()
{
KIRQL irql = KeRaiseIrqlToDpcLevel();
UINT64 cr0 = __readcr0();
cr0 &= 0xfffffffffffeffff;
__writecr0(cr0);
_disable();
return irql;
}
void WPONx64(KIRQL irql)
{
UINT64 cr0 = __readcr0();
cr0 |= 0x10000;
_enable();
__writecr0(cr0);
KeLowerIrql(irql);
}
PVOID GetFunctionAddr(PCWSTR FunctionName)
{
UNICODE_STRING UniCodeFunctionName;
RtlInitUnicodeString(&UniCodeFunctionName, FunctionName);
return MmGetSystemRoutineAddress(&UniCodeFunctionName);
}
ULONG GetPatchSize(PUCHAR Address)
{
ULONG LenCount = 0, Len = 0;
while (LenCount < 14) //至少需要14字节
{
Len = lde_disasm(Address, 64);
Address = Address + Len;
LenCount = LenCount + Len;
}
return LenCount;
}
//传入:待HOOK函数地址,代理函数地址,接收原始函数地址的指针,接收补丁长度的指针;返回:原来头N字节的数据
PVOID HookKernelApi(IN PVOID ApiAddress, IN PVOID Proxy_ApiAddress, OUT PVOID* Original_ApiAddress, OUT ULONG* PatchSize)
{
KIRQL irql;
UINT64 tmpv;
PVOID head_n_byte, ori_func;
UCHAR jmp_code[] = "\xFF\x25\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF";
UCHAR jmp_code_orifunc[] = "\xFF\x25\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF";
*PatchSize = GetPatchSize((PUCHAR)ApiAddress);
head_n_byte = kmalloc(*PatchSize);
irql = WPOFFx64();
memcpy(head_n_byte, ApiAddress, *PatchSize);
WPONx64(irql);
//step 2: Create ori function
ori_func = kmalloc(*PatchSize + 14);
RtlFillMemory(ori_func, *PatchSize + 14, 0x90);
tmpv = (ULONG64)ApiAddress + *PatchSize;
memcpy(jmp_code_orifunc + 6, &tmpv, 8);
memcpy((PUCHAR)ori_func, head_n_byte, *PatchSize);
memcpy((PUCHAR)ori_func + *PatchSize, jmp_code_orifunc, 14);
*Original_ApiAddress = ori_func;
//step 3: fill jmp code
tmpv = (UINT64)Proxy_ApiAddress;
memcpy(jmp_code + 6, &tmpv, 8);
//step 4: Fill NOP and hook
irql = WPOFFx64();
RtlFillMemory(ApiAddress, *PatchSize, 0x90);
memcpy(ApiAddress, jmp_code, 14);
WPONx64(irql);
return head_n_byte;
}
//
VOID UnhookKernelApi(IN PVOID ApiAddress, IN PVOID OriCode, IN ULONG PatchSize)
{
KIRQL irql;
irql = WPOFFx64();
memcpy(ApiAddress, OriCode, PatchSize);
WPONx64(irql);
//todo : need release alloc memory
}