hook NtTerminateProcess进行应用的保护

这段时间在学习驱动,然后看到hook ssdt的代码,找了一个写的清晰的学习了一下:http://www.netfairy.net/?post=218

 

这里是hook NtOpenProcess,但是想自己练手所以hook NtTerminateProcess,经过多次蓝屏后,然后这里记录一下

 

  • 遇到的问题

由于所学的例子是通过应用程序获取pid来控制保护的进程,但是ZwTerminateProcess不能通过参数获得PID,那如何获取PID呢?

  • 解决方案

通过ZwQueryInformationProcess获得ProcessInformation再获得PID

  • 环境

开发配置:vs2015  x86  debug

测试环境:xp sp3

驱动代码

  1 #include <ntddk.h>
  2 
  3 #define NT_DEVICE_NAME L"\Device\ProtectProcess"
  4 #define DOS_DEVICE_NAME L"\DosDevices\ProtectProcess"
  5 
  6 #define IOCTL_PROTECT_CONTROL CTL_CODE(FILE_DEVICE_UNKNOWN, 0x800, METHOD_BUFFERED, FILE_ANY_ACCESS)
  7 
  8 
  9 #pragma pack(1)        //SSDT表的结构
 10 typedef struct ServiceDescriptorEntry
 11 {
 12   unsigned int *ServiceTableBase;
 13   unsigned int *ServiceCounterTableBase; //Used only in checked build
 14   unsigned int NumberOfServices;
 15   unsigned char *ParamTableBase;
 16 } ServiceDescriptorTableEntry_t, *PServiceDescriptorTableEntry_t;
 17 #pragma pack()
 18 
 19 __declspec(dllimport) ServiceDescriptorTableEntry_t KeServiceDescriptorTable;        //变量名是不能变的,因为是从外部导入
 20 
 21                                            //这个用于查询某个函数的地址的宏定义
 22 #define SYSTEMSERVICE(_function) KeServiceDescriptorTable.ServiceTableBase[*(PULONG)((PUCHAR)_function+1)]
 23 
 24 NTSYSAPI NTSTATUS NTAPI ZwQueryInformationProcess(
 25   IN HANDLE ProcessHandle,
 26   IN PROCESSINFOCLASS ProcessInformationClass,
 27   OUT PVOID ProcessInformation,
 28   IN ULONG ProcessInformationLength,
 29   OUT PULONG ReturnLength);
 30 
 31 NTSYSAPI NTSTATUS NTAPI ZwTerminateProcess(
 32   IN HANDLE ProcessHandle OPTIONAL,
 33   IN NTSTATUS ExitStatus);
 34 
 35 
 36 typedef NTSTATUS (*ZWTERMINATEPROCESS)(
 37   IN HANDLE ProcessHandle OPTIONAL,
 38   IN NTSTATUS ExitStatus);
 39 
 40 ZWTERMINATEPROCESS OldZwTerminateProcess;
 41 long pid = -1;
 42 
 43 NTSTATUS DispatchDeviceControl(IN PDEVICE_OBJECT deviceObject, IN PIRP Irp)
 44 {
 45   NTSTATUS nStatus = STATUS_SUCCESS;
 46   ULONG IoControlCode = 0;
 47   PIO_STACK_LOCATION IrpStack = NULL;
 48 
 49   long* inBuf = NULL;
 50   char* outBuf = NULL;
 51   ULONG inSize = 0;
 52   ULONG outSize = 0;
 53   PCHAR buffer = NULL;
 54   PMDL mdl = NULL;
 55 
 56   Irp->IoStatus.Status = STATUS_SUCCESS;
 57   Irp->IoStatus.Information = 0;
 58 
 59   IrpStack = IoGetCurrentIrpStackLocation(Irp);    //利用函数获得当前请求任务的参数
 60   switch (IrpStack->MajorFunction)
 61   {
 62   case IRP_MJ_CREATE:
 63     DbgPrint("IRP_MJ_CREATE被调用
");
 64     break;
 65   case IRP_MJ_CLOSE:
 66     DbgPrint("IRP_MJ_CLOSE被调用
");
 67     break;
 68   case IRP_MJ_DEVICE_CONTROL:
 69     DbgPrint("IRP_MJ_DEVICE_CONTROL被调用
");
 70     IoControlCode = IrpStack->Parameters.DeviceIoControl.IoControlCode;
 71     switch (IoControlCode)
 72     {
 73     case IOCTL_PROTECT_CONTROL:
 74       inSize = IrpStack->Parameters.DeviceIoControl.InputBufferLength;
 75       outSize = IrpStack->Parameters.DeviceIoControl.OutputBufferLength;
 76 
 77       inBuf = (long*)Irp->AssociatedIrp.SystemBuffer;
 78       pid = *inBuf;
 79       DbgPrint("==================================");
 80       DbgPrint("IOCTL_PROTECT_CONTROL被调用,通讯成功
");
 81       DbgPrint("输入缓冲区大小:%d
", inSize);
 82       DbgPrint("输出缓冲区大小:%d
", outSize);
 83       DbgPrint("输入缓冲区内容:%ld
", inBuf);
 84       DbgPrint("当前保护进程ID:%ld
", pid);
 85       DbgPrint("==================================");
 86       break;
 87     default:
 88       break;
 89     }
 90     break;
 91   default:
 92     DbgPrint("未知请求包被调用
");
 93     break;
 94   }
 95 
 96   nStatus = Irp->IoStatus.Status;
 97 
 98   IoCompleteRequest(Irp, IO_NO_INCREMENT);
 99 
100   return nStatus;
101 }
102 
103 NTSTATUS NewZwTerminateProcess(
104   IN HANDLE ProcessHandle OPTIONAL,
105   IN NTSTATUS ExitStatus)
106 {
107   NTSTATUS nStatus = STATUS_SUCCESS;
108   
109   ULONG Ret;
110   PROCESS_BASIC_INFORMATION pbi;
111 
112   //pBuffer = ExAllocatePool(PagedPool, sizeof(PROCESS_BASIC_INFORMATION));
113   ZwQueryInformationProcess(ProcessHandle, ProcessBasicInformation, (PVOID)&pbi, sizeof(PROCESS_BASIC_INFORMATION), &Ret);
114 
115 
116   if (pbi.UniqueProcessId == pid)
117   {
118     DbgPrint("保护进程不被关闭:%d
", pid);
119     return STATUS_ACCESS_DENIED;
120   }
121 
122   nStatus = OldZwTerminateProcess(ProcessHandle, ExitStatus);
123   return STATUS_SUCCESS;
124 }
125 
126 VOID DriverUnload(PDRIVER_OBJECT pDriverObject)
127 {
128   UNICODE_STRING DeviceLinkString;
129   PDEVICE_OBJECT DeviceObjectTemp1 = NULL;
130   PDEVICE_OBJECT DeviceObjectTemp2 = NULL;
131 
132   DbgPrint("Driver Unload
");
133 
134   RtlInitUnicodeString(&DeviceLinkString, DOS_DEVICE_NAME);
135   IoDeleteSymbolicLink(&DeviceLinkString);
136   if (pDriverObject)
137   {
138     DeviceObjectTemp1 = pDriverObject->DeviceObject;
139     while (DeviceObjectTemp1)
140     {
141       DeviceObjectTemp2 = DeviceObjectTemp1;
142       DeviceObjectTemp1 = DeviceObjectTemp1->NextDevice;
143       IoDeleteDevice(DeviceObjectTemp2);
144     }
145   }
146 
147   DbgPrint("设备已经卸载
");
148   DbgPrint("修复SSDT表
");
149   (ZWTERMINATEPROCESS)(SYSTEMSERVICE(ZwTerminateProcess)) = OldZwTerminateProcess;
150   DbgPrint("驱动卸载完毕
");
151 }
152 
153 NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegPath)
154 {
155   NTSTATUS ntStatus = STATUS_SUCCESS;
156   UNICODE_STRING ntDeviceName;
157   UNICODE_STRING DeviceLinkString;
158   PDEVICE_OBJECT deviceObject = NULL;
159 
160   RtlInitUnicodeString(&ntDeviceName, NT_DEVICE_NAME);
161 
162   ntStatus = IoCreateDevice(
163     pDriverObject,
164     0,
165     &ntDeviceName,
166     FILE_DEVICE_UNKNOWN,
167     0,
168     FALSE,
169     &deviceObject);
170 
171   if (!NT_SUCCESS(ntStatus))
172   {
173     DbgPrint("无法创建驱动设备");
174     return ntStatus;
175   }
176 
177   RtlInitUnicodeString(&DeviceLinkString, DOS_DEVICE_NAME);
178   ntStatus = IoCreateSymbolicLink(&DeviceLinkString, &ntDeviceName);
179 
180   if (!NT_SUCCESS(ntStatus))
181   {
182     return ntStatus;
183   }
184 
185   pDriverObject->MajorFunction[IRP_MJ_CREATE] = DispatchDeviceControl;
186   pDriverObject->MajorFunction[IRP_MJ_CLOSE] = DispatchDeviceControl;
187   pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchDeviceControl;
188   pDriverObject->DriverUnload = DriverUnload;
189 
190   DbgPrint("驱动程序已经启动
");
191   DbgPrint("修改SSDT表。。。
");
192 
193   //修改ZwTerminateProcess函数地址
194   //将原来ssdt中所要hook的函数地址换成我们自己的函数地址
195   OldZwTerminateProcess = (ZWTERMINATEPROCESS)(SYSTEMSERVICE(ZwTerminateProcess));
196   SYSTEMSERVICE(ZwTerminateProcess) = (unsigned int)NewZwTerminateProcess;
197 
198   DbgPrint("驱动程序加载完毕
");
199 
200   return STATUS_SUCCESS;
201 }

控制程序与上面所给链接的代码相同

原文地址:https://www.cnblogs.com/QKSword/p/9960140.html