Note
Search…
SSDT_HOOK
由 SSDT HOOk 实现的进程保护框架
1
#include <ntddk.h>
2
#include<ntstatus.h>
3
4
//1.找到系统服务表的函数地址表
5
6
//定义一个全局变量用来存放之前的NtOpenProcess地址
7
ULONG uOldNtOpenProcess;
8
9
10
//有了地址还需要一个函数NtOpenProcess指针,用于调用原来的NtOpenProcess
11
typedef NTSTATUS(*NTOPENPROCESS)(
12
__out PHANDLE ProcessHandle,
13
__in ACCESS_MASK DesiredAccess,
14
__in POBJECT_ATTRIBUTES ObjectAttributes,
15
__in_opt PCLIENT_ID ClientId
16
);
17
18
typedef struct _KSYSTEM_SERVICE_TABLE
19
{
20
PULONG ServiceTableBase; // SSDT (System Service Dispatch Table)的基地址
21
PULONG ServiceCounterTableBase; // 用于 checked builds, 包含 SSDT 中每个服务被调用的次数
22
ULONG NumberOfService; // 服务函数的个数, NumberOfService * 4 就是整个地址表的大小
23
PULONG ParamTableBase; // SSPT(System Service Parameter Table)的基地址
24
} KSYSTEM_SERVICE_TABLE, *PKSYSTEM_SERVICE_TABLE;
25
26
typedef struct _KSERVICE_TABLE_DESCRIPTOR
27
{
28
KSYSTEM_SERVICE_TABLE ntoskrnl; // ntoskrnl.exe 的服务函数
29
KSYSTEM_SERVICE_TABLE win32k; // win32k.sys 的服务函数(GDI32.dll/User32.dll 的内核支持)
30
KSYSTEM_SERVICE_TABLE notUsed1;
31
KSYSTEM_SERVICE_TABLE notUsed2;
32
}KSERVICE_TABLE_DESCRIPTOR, *PKSERVICE_TABLE_DESCRIPTOR;
33
34
35
//导出由 ntoskrnl所导出的 SSDT
36
extern PKSERVICE_TABLE_DESCRIPTOR KeServiceDescriptorTable;//这个是导出的,要到内核文件找,所以名字不能瞎起
37
38
//准备用于替换的函数
39
NTSTATUS NTAPI MyNtOpenProcess(__out PHANDLE ProcessHandle,
40
__in ACCESS_MASK DesiredAccess,
41
__in POBJECT_ATTRIBUTES ObjectAttributes,
42
__in_opt PCLIENT_ID ClientId
43
)
44
{
45
NTSTATUS Status;
46
Status = STATUS_SUCCESS;
47
if (ClientId->UniqueProcess == (HANDLE)916)//指定保护的进程ID
48
{
49
return STATUS_ABANDONED;
50
}
51
//打开原来的函数,因为这个函数也要实现原来的功能,不然就乱套了,除非你自己在自己业务里实现了
52
return ((NTOPENPROCESS)uOldNtOpenProcess)(ProcessHandle, DesiredAccess, ObjectAttributes, ClientId);
53
}
54
55
void PageProtectOff() {
56
57
__asm { //关闭内存保护
58
push eax;
59
mov eax, cr0;
60
and eax, ~0x10000;
61
mov cr0, eax;
62
pop eax;
63
}
64
}
65
66
void PageProtectOn() {
67
68
__asm { //恢复内存保护
69
push eax;
70
mov eax, cr0;
71
or eax, 0x10000;
72
mov cr0, eax;
73
pop eax;
74
}
75
}
76
77
//3.修改函数地址,准备个函数用来修改函数地址
78
void HookNtOpenProcess() {
79
NTSTATUS Status;
80
Status = STATUS_SUCCESS;
81
PageProtectOff();
82
uOldNtOpenProcess = KeServiceDescriptorTable->ntoskrnl.ServiceTableBase[0xBE];
83
KeServiceDescriptorTable->ntoskrnl.ServiceTableBase[0xBE] = (ULONG)MyNtOpenProcess;
84
PageProtectOn();
85
}
86
87
//4.恢复
88
void UnHookNtOpenProcess() {
89
PageProtectOff();
90
KeServiceDescriptorTable->ntoskrnl.ServiceTableBase[0xBE] = (ULONG)uOldNtOpenProcess;
91
PageProtectOn();
92
}
93
94
VOID DriverUnload(PDRIVER_OBJECT pDriver) {
95
UNREFERENCED_PARAMETER(pDriver);
96
UnHookNtOpenProcess();
97
98
KdPrint(("My Dirver is unloading..."));
99
100
}
101
102
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriver, PUNICODE_STRING pPath) {
103
UNREFERENCED_PARAMETER(pPath);
104
KdPrint(("->%x \n", KeServiceDescriptorTable->ntoskrnl.ServiceTableBase[0xBE]));//得到函数地址表
105
106
HookNtOpenProcess();
107
108
pDriver->DriverUnload = DriverUnload;
109
return STATUS_SUCCESS;
110
}
Copied!
Copy link