继续写一下学习驱动的成果,看大佬的文章介绍了枚举系统进程和禁止创建新进程,最后自己结合一下写了每当进程被创建时,通过检查新创建的进程名来杀死想要结束的进程。
使用函数RtlCompareUnicodeString对比进程名的字符串时会出现蓝屏的问题
对比的两个参数都用RtlInitUnicodeString进行赋值后进行对比
开发配置:vs2015 x86 debug
测试环境:xp sp3
驱动代码
1 #include <ntddk.h>
2
3 #define SystemProcessesAndThreadsInformation 5
4 #define KillProcess L"League of Legends.exe"
5
6 NTKERNELAPI NTSTATUS ZwQuerySystemInformation(
7 IN ULONG SystemInformationClass,
8 IN OUT PVOID SystemInformation,
9 IN ULONG SystemInformationLength,
10 OUT PULONG ReturnLength OPTIONAL);
11
12 typedef struct _SYSTEM_PROCESSES
13 {
14 ULONG NextEntryDelta;
15 ULONG ThreadCount;
16 ULONG Reserved[6];
17 LARGE_INTEGER CreateTime;
18 LARGE_INTEGER UserTime;
19 LARGE_INTEGER KernelTime;
20 UNICODE_STRING ProcessName;
21 KPRIORITY BasePriority;
22 ULONG ProcessId;
23 ULONG InheritedFromProcessId;
24 ULONG HandleCount;
25 ULONG Reserved2[2];
26 VM_COUNTERS VmCounters;
27 IO_COUNTERS IoCounters;
28 } _SYSTEM_PROCESSES, *PSYSTEM_PROCESSES;
29
30 //进程监控回调函数
31 VOID ProcessMonitorCallback(IN HANDLE hParentId, IN HANDLE hProcessId, IN BOOLEAN bCreate)
32 {
33 HANDLE procHandle = NULL;
34 CLIENT_ID ClientId;
35 ULONG cbBuffer = 0x8000; //等下开辟缓冲区的长度,先设为0x8000字节
36 PVOID pBuffer = NULL; //用来执行缓冲区
37 NTSTATUS Status; //返回值,等下获取信息的返回值放这里面
38 PCWSTR pszProcessName; //进程名
39 UNICODE_STRING ProcessName;
40 UNICODE_STRING killprocess;
41 PSYSTEM_PROCESSES pInfo; //指向SYSTEM_PROCESSES的指针
42
43 OBJECT_ATTRIBUTES Obja;
44 Obja.Length = sizeof(Obja);
45 Obja.RootDirectory = 0;
46 Obja.ObjectName = 0;
47 Obja.Attributes = 0;
48 Obja.SecurityDescriptor = 0;
49 Obja.SecurityQualityOfService = 0;
50 ClientId.UniqueProcess = (HANDLE)hProcessId;
51 ClientId.UniqueThread = 0;
52
53
54 if (bCreate) //bCreate为true表示创建程序
55 {
56 //有创建的进程则进行一次扫描
57 do
58 {
59 pBuffer = ExAllocatePool(NonPagedPool, cbBuffer); //开辟内存,这里需要非分页内存
60 if (pBuffer == NULL)
61 {
62 return; //申请不成功,直接返回失败,不继续了
63 }
64 Status = ZwQuerySystemInformation(SystemProcessesAndThreadsInformation, pBuffer, cbBuffer, NULL); //获取进程信息
65 if (Status == STATUS_INFO_LENGTH_MISMATCH) //缓冲区不足,释放缓冲区重新分配
66 {
67 ExFreePool(pBuffer);
68 cbBuffer *= 2;
69 }
70 else if (!NT_SUCCESS(Status)) //其它错误,直接返回失败,不继续
71 {
72 ExFreePool(pBuffer);
73 return;
74 }
75 }
76 while (Status == STATUS_INFO_LENGTH_MISMATCH);//直到有充足的缓冲区
77 DbgPrint("分配内存成功
");
78
79 pInfo = (PSYSTEM_PROCESSES)pBuffer; //返回来的进程信息
80 while (1)
81 {
82 pszProcessName = (PCWSTR)pInfo->ProcessName.Buffer; //获取进程名
83
84 //进行对比
85 RtlInitUnicodeString(&killprocess, KillProcess);
86 RtlInitUnicodeString(&ProcessName, pszProcessName);
87 Status = RtlCompareUnicodeString(&killprocess, &ProcessName, TRUE);
88 if (Status == 0)
89 {
90 DbgPrint("捕获到想查杀的程序,进行关闭
");
91 //调用函数ZwOpenProcess函数,通过进程pid号获得进程句柄
92 ZwOpenProcess(&procHandle, PROCESS_ALL_ACCESS, &Obja, &ClientId);
93 if (procHandle != NULL)
94 {
95 Status = ZwTerminateProcess(procHandle, 1);
96 }
97 else
98 {
99 DbgPrint("failed to ZwOpenProcess...
");
100 return;
101 }
102 }
103
104 if (pInfo->NextEntryDelta == 0) //如果没有下一个就结束
105 {
106 break;
107 }
108
109 pInfo = (PSYSTEM_PROCESSES)(((PUCHAR)pInfo) + pInfo->NextEntryDelta); //指向下一个
110 }
111
112 ExFreePool(pBuffer); //全部结束,释放内存
113 }
114
115 //这里是我来判断没有成功结束进程用的
116 switch (Status)
117 {
118 case STATUS_SUCCESS:
119 DbgPrint("process %u has beed killed ...
", hProcessId);
120 break;
121 case STATUS_OBJECT_TYPE_MISMATCH:
122 DbgPrint("failed to kill %u process,The specified handle is not a process handle.
", hProcessId);
123 break;
124 case STATUS_INVALID_HANDLE:
125 DbgPrint("failed to kill %u process,The specified handle is not valid.
", hProcessId);
126 break;
127 case STATUS_ACCESS_DENIED:
128 DbgPrint("failed to kill %u process,The driver cannot access the specified process object.
", hProcessId);
129 break;
130 case STATUS_PROCESS_IS_TERMINATING:
131 DbgPrint("failed to kill %u process,The specified process is already terminating.
", hProcessId);
132 break;
133 default:
134 break;
135 }
136 }
137
138 void DriverUnload(PDRIVER_OBJECT pDriverObject)
139 {
140 PsSetCreateProcessNotifyRoutine(ProcessMonitorCallback, TRUE);
141 DbgPrint("driver Unload
");
142 }
143
144 NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING RegistryPath)
145 {
146 NTSTATUS status = STATUS_SUCCESS;
147 pDriverObject->DriverUnload = DriverUnload;
148
149 DbgPrint("加载驱动成功
");
150 status = PsSetCreateProcessNotifyRoutine(ProcessMonitorCallback, FALSE); //创建进程回调
151 if (status == STATUS_INVALID_PARAMETER)
152 {
153 DbgPrint("给定的进程回调已注册或系统已达到系统回调上限");
154 }
155 return status;
156 }