这段时间在学习驱动,然后看到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 }