通过驱动杀死那个进程
继续写一下学习驱动的成果,看大佬的文章介绍了枚举系统进程和禁止创建新进程,最后自己结合一下写了每当进程被创建时,通过检查新创建的进程名来杀死想要结束的进程。
- 遇到的问题
使用函数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("分配内存成功\n"); 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("捕获到想查杀的程序,进行关闭\n"); 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...\n"); 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 ...\n", hProcessId); 120 break; 121 case STATUS_OBJECT_TYPE_MISMATCH: 122 DbgPrint("failed to kill %u process,The specified handle is not a process handle. \n", hProcessId); 123 break; 124 case STATUS_INVALID_HANDLE: 125 DbgPrint("failed to kill %u process,The specified handle is not valid.\n", hProcessId); 126 break; 127 case STATUS_ACCESS_DENIED: 128 DbgPrint("failed to kill %u process,The driver cannot access the specified process object.\n", hProcessId); 129 break; 130 case STATUS_PROCESS_IS_TERMINATING: 131 DbgPrint("failed to kill %u process,The specified process is already terminating.\n", 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\n"); 142 } 143 144 NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING RegistryPath) 145 { 146 NTSTATUS status = STATUS_SUCCESS; 147 pDriverObject->DriverUnload = DriverUnload; 148 149 DbgPrint("加载驱动成功\n"); 150 status = PsSetCreateProcessNotifyRoutine(ProcessMonitorCallback, FALSE); //创建进程回调 151 if (status == STATUS_INVALID_PARAMETER) 152 { 153 DbgPrint("给定的进程回调已注册或系统已达到系统回调上限"); 154 } 155 return status; 156 }
谦谦君子,卑以自牧