Hook SSDT中NtCreateProcessEx

  1 #ifdef __cplusplus
  2 extern "C"
  3 {
  4 #endif
  5 #include <ntddk.h>
  6 #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序号
posted @ 2013-09-20 23:12  JoyChou  阅读(1005)  评论(0编辑  收藏  举报