2013年9月24日星期二

ssdt_hook NtOpenProcess

 
    
 
    
 
  Get a list of all functions ssdt address  
 
  
   for (int i = 0; i NumberOfServices; i + +)   
  
   {   
  
   KdPrint (("NumberOfService [% d] -------% X \ n", i, KeServiceDescriptorTable-> ServiceTableBase [i]));   
  
   }   
  
      
  
      
  
   
    
      need to be defined     
    
     typedef struct _ServiceDescriptorTable {     
    
     unsigned int * ServiceTableBase; / / System Service Dispatch Table base address     
    
     unsigned int * ServiceCounterTable;     
    
     / / Contains the SSDT is the number of calls per service counter . This counter is generally sysenter update.     
    
     unsigned int NumberOfServices ;/ / ServiceTableBase described by a number of services .     
    
     unsigned char * ParamTableBase; / / parameter contains the number of bytes for each system service table base address - system service parameter table     
    
     } * PServiceDescriptorTable;     
    
          
    
     extern "C" extern PServiceDescriptorTable KeServiceDescriptorTable;     
   
   
        
   
     process :    
   
     1, in ssdt_hook () function to save to hook function (NtOpenProcess) address    
   
     2, the original ssdt the address of the function you want to hook into our own function address    
   
     3, in UnHookSsdt ssdt restore the original function address in    
   
        
   
     When the driver loaded successfully , the first implementation DriverEntry inside ssdt_hook () function , then we open our CE protection processes ,    
   
     will run into my own defined function MyNtOpenProcess ()    
   
     finally uninstall the driver , perform Driver_Unload () inside UnHookSsdt () function    
   
        
   
        
   
        
   
    
      role :     
    
     Prevent other processes using OpenProcess open, eg Cheat Engine     
    
          
    
      Note :     
    
     Modify the address , it should first remove page protectors , and then resume page protection     
    
     
      Use the PsLookupProcessByProcessId , you must use ObDereferenceObject recycling !      
     
      PsLookupProcessByProcessId EPROCESS structure for the specified process , the purpose is to get the process name      
    
    
          
    
      Summary :     
    
     ssdt_hook code like this,     
    
     ssdt_hook () function to hook inside the first save the address , and then modify their own definition of the function address,     
    
     UnSsdt_hook () function which is to restore the address     
    
     And define their own function inside that function to be restored before     
    
          
    
     
      VOID UnHookSsdt ()      
     
      {      
     
      PageProtectOff ();      
     
      KeServiceDescriptorTable-> ServiceTableBase [122] = O_NtOpenProcess; / / restore the original function address ssdt      
     
      PageProtectOn ();      
     
      }      
     
            
     
      NTSTATUS HookSsdt ()      
     
      {      
     
      / / 1, in the ssdt_hook () function to save to hook function (NtOpenProcess) address      
     
      O_NtOpenProcess = KeServiceDescriptorTable-> ServiceTableBase [122];      
     
      PageProtectOff ();      
     
      / / 2 , the original ssdt the address of the function you want to hook into our own function address      
     
      KeServiceDescriptorTable-> ServiceTableBase [122] = (unsigned int) MyNtOpenProcess;      
     
      / /        time we open with CE process is protected , it will call our own function      
     
      PageProtectOn ();      
     
            
     
      return STATUS_SUCCESS;      
     
      }      
     
            
    
    
      effect :     
    
          
    
          
    
     cpp code :     
    
     
      
  1 #ifdef __cplusplus 
2 extern "C"
3 {
4 #_endif
5 #include <ntddk.h>
6 #ifdef __cplusplus
7 }
8 #_endif
9
10 typedef struct _ServiceDescriptorTable {
11 unsigned int* ServiceTableBase; //System Service Dispatch Table 的基地址
12 unsigned int* ServiceCounterTable;
13 //包含着 SSDT 中每个服务被调用次数的计数器。这个计数器一般由sysenter 更新。
14 unsigned int NumberOfServices;//由 ServiceTableBase 描述的服务的数目。
15 unsigned char* ParamTableBase; //包含每个系统服务参数字节数表的基地址-系统服务参数表
16 }*PServiceDescriptorTable;
17
18 extern "C" extern PServiceDescriptorTable KeServiceDescriptorTable;
19
20 typedef NTSTATUS(*MYNTOPENPROCESS)(
21 OUT PHANDLE ProcessHandle,
22 IN ACCESS_MASK AccessMask,
23 IN POBJECT_ATTRIBUTES ObjectAttributes,
24 IN PCLIENT_ID ClientId );//定义一个函数指针,用于下面对O_NtOpenProcess进行强制转换
25
26 ULONG O_NtOpenProcess = 0;
27
28 extern "C" NTSTATUS
29 PsLookupProcessByProcessId(
30 IN HANDLE ProcessId,
31 OUT PEPROCESS *Process
32 );
33
34 void PageProtectOff()//关闭页面保护
35 {
36 __asm{
37 cli
38 mov eax,cr0
39 and eax,not 10000h
40 mov cr0,eax
41 }
42 }
43 void PageProtectOn()//打开页面保护
44 {
45 __asm{
46 mov eax,cr0
47 or eax,10000h
48 mov cr0,eax
49 sti
50 }
51 }
52
53 // 判断是否打开的是自己想保护的进程
54 BOOLEAN ProtectProcess(HANDLE ProcessId,char *str_ProtectObjName)
55 {
56 NTSTATUS status;
57 PEPROCESS process_obj;
58
59 if(!MmIsAddressValid(str_ProtectObjName))//这个条件是用来判断目标进程名是否有效
60 {
61 return FALSE;
62 }
63 if(ProcessId == 0)//这个条件是用来排除System Idle Process进程的干扰
64 {
65 return FALSE;
66 }
67 status=PsLookupProcessByProcessId(ProcessId, &process_obj);//这句用来获取目标进程的EPROCESS结构
68 if(!NT_SUCCESS(status))
69 {
70 KdPrint(("我错了,这个是错误号:%X---这个是进程ID:%d\n",status,ProcessId));
71 return FALSE;
72 }
73 if(!strcmp((char *)process_obj + 0x174, str_ProtectObjName))//进行比较
74 {
75 ObDereferenceObject(process_obj);//对象计数器减1,为了恢复对象管理器计数,便于回收
76 return TRUE;
77 }
78 ObDereferenceObject(process_obj);
79 return FALSE;
80 //使用了PsLookupProcessByProcessId后,必须用ObDereferenceObject回收!
81 //PsLookupProcessByProcessId获取指定进程的EPROCESS结构,目的就是获取进程名
82 }
83 NTSTATUS MyNtOpenProcess (
84 __out PHANDLE ProcessHandle,
85 __in ACCESS_MASK DesiredAccess,
86 __in POBJECT_ATTRIBUTES ObjectAttributes,
87 __in_opt PCLIENT_ID ClientId
88 )
89 {
90 if(ProtectProcess(ClientId->UniqueProcess,"notepad.exe")) // 如果打开的进程是目标进程
91 {
92 KdPrint(("%s打开文件失败\n",(char *)PsGetCurrentProcess()+0x174));
93 return STATUS_UNSUCCESSFUL; // 这是一个关键,设置STATUS_UNSUCCESSFUL,CE就会提示打开不成功
94 }
95
96 return ((MYNTOPENPROCESS)O_NtOpenProcess)(ProcessHandle,//处理完自己的任务后,调用原来的函数,让其它进程正常工作
97 DesiredAccess,
98 ObjectAttributes,
99 ClientId);
100 }
101
102
103 VOID UnHookSsdt()
104 {
105 PageProtectOff();
106 KeServiceDescriptorTable->ServiceTableBase[122] = O_NtOpenProcess; //恢复ssdt中原来的函数地址
107 PageProtectOn();
108 }
109 NTSTATUS HookSsdt()
110 {
111 // 1、在ssdt_hook()函数中保存要hook函数的(NtOpenProcess)地址
112 O_NtOpenProcess = KeServiceDescriptorTable->ServiceTableBase[122];
113 PageProtectOff();
114 // 2、将原来ssdt中所要hook的函数地址换成我们自己的函数地址
115 KeServiceDescriptorTable->ServiceTableBase[122] = (unsigned int)MyNtOpenProcess;
116 // 此时我们用CE打开被保护的进程,就会调用我们自己的函数
117 PageProtectOn();
118
119 return STATUS_SUCCESS;
120 }
121 VOID DriverUnload(PDRIVER_OBJECT pDriverObject)
122 {
123 UnHookSsdt();
124 KdPrint(("Driver Unload Success !\n"));
125 }
126
127 extern "C" NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegistryPath )
128 {
129 KdPrint(("Welcome to My Driver\n"));
130 pDriverObject->DriverUnload = DriverUnload;
131 /* 所有函数的地址
132 for (int i = 0; i < KeServiceDescriptorTable->NumberOfServices; i++)
133 {
134 KdPrint(("NumberOfService[%d]-------%X\n", i, KeServiceDescriptorTable->ServiceTableBase[i]));
135 }*/
136 HookSsdt();
137 return STATUS_SUCCESS;
138 }
     
     

    
   
  
 

没有评论:

发表评论