【驱动】保护进程

概述:windows 驱动实现对进程的保护

0x01 说明

主要的逻辑是在驱动中 hook NtTerminateProcess 函数

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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
#include <Ntifs.h>


//0x7A NTOpenProcess
//0x101 NtTerminateProcess
#define FuctionID 0x101 //调用号

void PageProtectOn()
{
//恢复内存保护
__asm
{
mov eax,cr0
or eax,10000h
mov cr0,eax
sti
}
}

void PageProtectOff()
{
//去掉内存保护
__asm
{
cli
mov eax,cr0
and eax,not 10000h
mov cr0,eax
}
}

//1、找到系统服务表:函数地址表
typedef struct _KSYSTEM_SERVICE_TABLE
{
PULONG ServiceTableBase; //函数地址表基地址
PULONG ServiceCounterTableBase; //被访问了多少次
ULONG NumberOfService; //表中服务函数的总数
PUCHAR ParamTableBase; //服务函数的参数个数数组的起始地址
}KSYSTEM_SERVICE_TABLE,*PKSYSTEM_SERVICE_TABLE;

typedef struct _KSERVICE_DESCRIPTOR_TABLE
{
KSYSTEM_SERVICE_TABLE ntoskrnl;//ntoskrnl.exe的函数
KSYSTEM_SERVICE_TABLE win32k;//win32k.sys的函数
KSYSTEM_SERVICE_TABLE notUsed1;//
KSYSTEM_SERVICE_TABLE notUsed2;//
}KSERVICE_DESCRIPTOR_TABLE,*PKSERVICE_DESCRIPTOR_TABLE;

//NtTerminateProcess函数指针
typedef NTSTATUS (*NTTERMINATEPROCESS) (HANDLE ProcessHandle, NTSTATUS ExitStatus);


//KeServiceDescriptorTable时ntoskrnl.exe所导出的全局变量 申明一下就可以直接用了
extern PKSERVICE_DESCRIPTOR_TABLE KeServiceDescriptorTable;
//存储原来的函数地址
ULONG uOldNtTerminateProcess;

//2.准备用于替换的函数
NTSTATUS MyNtTerminateProcess(HANDLE ProcessHandle, NTSTATUS ExitStatus)
{
//自己的业务..各种过滤 或者修改返回结果
PEPROCESS pEprocess;
NTSTATUS status;
PCHAR ImageFileName;


//通过句柄获取EPROCESS
status = ObReferenceObjectByHandle(ProcessHandle,FILE_ANY_ACCESS,*PsProcessType,KernelMode,&pEprocess,NULL);
if (!NT_SUCCESS(status))
{
return status;
}
//获取进程名字 _EPROCESS + 0x171 == ImageFileName
ImageFileName = (PCHAR)pEprocess + 0x174;
//判断是否是要保护的进程
if (strcmp(ImageFileName, "notepad.exe") == 0)
{
//判断如何退出
if (ProcessHandle == (HANDLE)0xFFFFFFFF)
{
//点X关闭
DbgPrint("点X关闭 成功退出:%s: NtTerminateProcess(%x, %x)\n", ImageFileName, ProcessHandle, ExitStatus);
return ((NTTERMINATEPROCESS)uOldNtTerminateProcess)(ProcessHandle, ExitStatus);
}
else if(ExitStatus == 1)
{
// 通过任务管理器关闭
DbgPrint("通过任务管理器关闭 拒绝关闭:%s: NtTerminateProcess(%x, %x)\n", ImageFileName, ProcessHandle, ExitStatus);
return STATUS_ACCESS_DENIED;
}
else
{
return STATUS_ACCESS_DENIED;
}
}

return ((NTTERMINATEPROCESS)uOldNtTerminateProcess)(ProcessHandle, ExitStatus);
}
//3.修改函数地址
NTSTATUS HookNtTerminateProcess()
{
NTSTATUS Status;
Status = STATUS_SUCCESS;
PageProtectOff();
uOldNtTerminateProcess = KeServiceDescriptorTable->ntoskrnl.ServiceTableBase[FuctionID];
KeServiceDescriptorTable->ntoskrnl.ServiceTableBase[FuctionID] = (ULONG)MyNtTerminateProcess;
PageProtectOn();
return Status;
}
//4.恢复
VOID UnHookNtTerminateProcess()
{
PageProtectOff();
KeServiceDescriptorTable->ntoskrnl.ServiceTableBase[FuctionID] = (ULONG)uOldNtTerminateProcess;
PageProtectOn();
}
//卸载函数
VOID DriverUnload(PDRIVER_OBJECT driver)
{
UnHookNtTerminateProcess();
KdPrint(("驱动程序停止运行了.\r\n"));
}

//入口函数,相当于main
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriver, PUNICODE_STRING reg_path)
{
HookNtTerminateProcess();

//注册销毁回调函数
pDriver->DriverUnload = DriverUnload;
return STATUS_SUCCESS;
}


【驱动】保护进程
https://hodlyounger.github.io/A_OS/Windows/驱动/【驱动】保护进程/
作者
mingming
发布于
2023年10月27日
许可协议