1 #ifdef __cplusplus 2 extern "C" 3 { 4 #endif 5 #include6 #ifdef __cplusplus 7 } 8 #endif 9 10 11 typedef struct _ServiceDescriptorTable { 12 unsigned int *ServiceTableBase; //System Service Dispatch Table 的基地址 13 unsigned int *ServiceCounterTable; 14 //包含着 SSDT 中每个服务被调用次数的计数器。这个计数器一般由sysenter 更新。 15 unsigned int NumberOfServices;//由 ServiceTableBase 描述的服务的数目。 16 unsigned int *ParamTableBase; //包含每个系统服务参数字节数表的基地址-系统服务参数表 17 }*PServiceDescriptorTable; 18 19 extern "C" extern PServiceDescriptorTable KeServiceDescriptorTable; 20 21 typedef NTSTATUS (*NTCREATEPROCESSEX)(PHANDLE ProcessHandle, 22 ACCESS_MASK DesiredAccess, 23 POBJECT_ATTRIBUTES oa, 24 HANDLE ParentProcess, 25 ULONG Flags, 26 HANDLE SectionHandle, 27 HANDLE DebugPort, 28 HANDLE ExceptionPort, 29 ULONG JobFlag); 30 31 ULONG O_NtCreateProcesseEx = 0; // 保存原始地址 32 33 // 去掉页面保护 34 VOID UN_PROTECT() 35 { 36 __asm 37 { 38 cli //关闭中断,增强这段代码的稳定性 39 push eax 40 mov eax, CR0 41 and eax, 0x0FFFEFFFF //使低17位为0 从右往左第17位 42 mov CR0, eax 43 pop eax 44 } 45 } 46 47 // 恢复页面保护 48 VOID RE_PROTECT() 49 { 50 __asm 51 { 52 push eax 53 mov eax, CR0 54 or eax,10000h //使低17位为1 55 mov CR0, eax 56 pop eax 57 sti //打开中断 58 } 59 } 60 61 62 63 //自己定义的函数,让程序执行的函数 64 NTSTATUS 65 MyNtCreateProcessEx( 66 PHANDLE ProcessHandle, 67 ACCESS_MASK DesiredAccess, 68 POBJECT_ATTRIBUTES oa, 69 HANDLE ParentProcess, 70 ULONG Flags, 71 HANDLE SectionHandle, 72 HANDLE DebugPort, 73 HANDLE ExceptionPort, 74 ULONG JobFlag) 75 { 76 KdPrint(("Hook NtCreateProcess Success\n")); 77 // 调用NtCreateProcessEx函数,为什么能够调用?因为地址因为替换成NtCreateProcessEx函数的地址 78 // 3 正常返回 79 return ((NTCREATEPROCESSEX)O_NtCreateProcesseEx)(ProcessHandle, 80 DesiredAccess, 81 oa, 82 ParentProcess, 83 Flags, 84 SectionHandle, 85 DebugPort, 86 ExceptionPort, 87 JobFlag); 88 89 90 } 91 92 VOID HookSsdt() 93 { 94 //1 保存 95 O_NtCreateProcesseEx = KeServiceDescriptorTable->ServiceTableBase[48]; 96 UN_PROTECT(); 97 // 2 替换 98 KeServiceDescriptorTable->ServiceTableBase[48] = (unsigned int )MyNtCreateProcessEx; 99 RE_PROTECT();100 }101 102 VOID UnHookSsdt()103 {104 // 4 替换回去105 KeServiceDescriptorTable->ServiceTableBase[48] = O_NtCreateProcesseEx;106 }107 VOID DriverUnload(PDRIVER_OBJECT pDriverObject)108 {109 UnHookSsdt();110 KdPrint(("Driver Unload Success\n"));111 }112 extern "C" NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegistryPath)113 {114 KdPrint(("Welcome to JoyChou's Driver\n"));115 116 pDriverObject->DriverUnload = DriverUnload;117 HookSsdt();118 return STATUS_SUCCESS;119 }
整个流程:
首先在DriverEntry调用HookCreateProcess()函数,该函数的作用是将SSDT表中NtCreateProcessEx()函数的地址替换为
MyNtCreatePocessEx()函数的地址。
而MyNtCreatePocessEx()函数是用来取代NtCreateProcessEx()函数的函数。
说明:
执行UN_PROTECT()后,CPU可以向标志为 只读的内存页进行写入操作。
写入完成后,执行RE_PROTECT()函数回复到原来的状态。
效果:
当加载驱动后,随意运行一个程序,用dbgview就能接受到“ Hook NtCreateProcess Success”成功提示字符串
环境:
XP SP3
注意:
ulNtCreateProcesseExAddr = ulSsdt + 48 * 4;//这的48根据自己的电脑SSDT表中NtCreateProcessEx序号