通过驱动杀死那个进程

继续写一下学习驱动的成果,看大佬的文章介绍了枚举系统进程禁止创建新进程,最后自己结合一下写了每当进程被创建时,通过检查新创建的进程名来杀死想要结束的进程。

  • 遇到的问题

使用函数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 }
原文地址:https://www.cnblogs.com/QKSword/p/10002595.html