IoTimerInLineHook

  1 #ifndef CXX_IOTIMERINLINEHOOK_H
  2 #    include "IoTimerInlineHook.h"
  3 #endif
  4 
  5 
  6 ULONG32           SSDT_NtOpenProcessIndex     = 0;
  7 pfnNtOpenProcess  Old_NtOpenProcess           = NULL;
  8 PULONG32          ServiceTableBase            = NULL;
  9 
 10 
 11 
 12 ULONG32           Old_NtOpenProcessOffset = 0;    //针对Win7 x64
 13 
 14 
 15 PVOID             NtOpenProcessPassCode        = NULL;           //释放内存
 16 PVOID             Old_NtOpenProcessHeaderBytes = NULL;           //释放内存
 17 
 18 NTSTATUS
 19 DriverEntry(PDRIVER_OBJECT DriverObject,PUNICODE_STRING RegisterPath)
 20 {
 21 
 22     NTSTATUS  Status;
 23     PDEVICE_OBJECT   DeviceObject = NULL;
 24     UNICODE_STRING   uniDeviceName;
 25 
 26 #ifdef _WIN64
 27     ULONG64   SSDTAddress = NULL;
 28     ULONG32   ulVariable  = 0;
 29 
 30     CHAR      szFindFunctionName[] = "ZwOpenProcess";
 31 
 32 
 33     if (GetSSDTAddressInWin7_X64(&SSDTAddress)==FALSE)
 34     {
 35         return STATUS_UNSUCCESSFUL;
 36     }
 37 
 38     DbgPrint("Win7_X64 SSDT:%p
",SSDTAddress);
 39     DbgPrint("Win7_X64 SSDTBase:%p
",((PSYSTEM_SERVICE_TABLE)SSDTAddress)->ServiceTableBase);
 40 
 41     
 42 
 43     if (GetSSDTFunctionIndexFromNtdllExportTableByFunctionNameInWin7_X64(szFindFunctionName,
 44         &SSDT_NtOpenProcessIndex)==FALSE)
 45     {
 46         return STATUS_UNSUCCESSFUL;
 47     }
 48 
 49     DbgPrint("Win7x64 SSDT_NtOpenProcessIndex:%d
",SSDT_NtOpenProcessIndex);
 50     
 51     
 52     
 53     ServiceTableBase   = (PULONG32)((PSYSTEM_SERVICE_TABLE)SSDTAddress)->ServiceTableBase;
 54     Old_NtOpenProcessOffset  = (ULONG32)(ServiceTableBase[SSDT_NtOpenProcessIndex]);
 55     ulVariable = Old_NtOpenProcessOffset>>4;
 56     Old_NtOpenProcess = (ULONG64)((PSYSTEM_SERVICE_TABLE)SSDTAddress)->ServiceTableBase + ulVariable;
 57     DbgPrint("Win7_X64 Old_NtOpenProcess:%p
",ulVariable);
 58 
 59 
 60 #else
 61     ULONG32   SSDTAddress      = NULL;
 62     CHAR      szFindFunctionName[] = "ZwOpenProcess";
 63     
 64     if (GetSSDTAddressInWinXP_X86(&SSDTAddress)==FALSE)
 65     {
 66         return STATUS_UNSUCCESSFUL;
 67     }
 68     DbgPrint("WinXP_X86 SSDT:%p
",SSDTAddress);
 69     DbgPrint("WinXP_X86 SSDTBase:%p
",((PSYSTEM_SERVICE_TABLE)SSDTAddress)->ServiceTableBase);
 70     
 71 
 72     if (GetSSDTFunctionIndexFromNtdllExportTableByFunctionNameInWinXP_X86(szFindFunctionName,
 73         &SSDT_NtOpenProcessIndex)==FALSE)
 74     {
 75         return STATUS_UNSUCCESSFUL;
 76     }
 77     DbgPrint("WinXP_X86 SSDT_NtOpenProcessIndex:%d
",SSDT_NtOpenProcessIndex);
 78 
 79     //先保存原先的函数地址
 80     ServiceTableBase   = (PULONG32)((PSYSTEM_SERVICE_TABLE)SSDTAddress)->ServiceTableBase;
 81     Old_NtOpenProcess  = (pfnNtOpenProcess)(ServiceTableBase[SSDT_NtOpenProcessIndex]);
 82     DbgPrint("WinXP_X86 Old_NtOpenProcess:%p
",Old_NtOpenProcess);
 83     
 84 #endif
 85 
 86     RtlInitUnicodeString(&uniDeviceName,DEVICE_NAME);
 87 
 88     Status = IoCreateDevice(DriverObject,0,&uniDeviceName,FILE_DEVICE_UNKNOWN,0,FALSE,&DeviceObject);
 89 
 90 
 91     if (!NT_SUCCESS(Status))
 92     {
 93         return Status;
 94     }
 95 
 96 
 97     IoInitializeTimer(DeviceObject,(PIO_TIMER_ROUTINE)CallBackProcedure,NULL);
 98     IoStartTimer(DeviceObject);
 99 
100 
101     DriverObject->DriverUnload = UnloadDriver;
102 
103     return Status;
104 }
105 
106 VOID
107     CallBackProcedure(PDEVICE_OBJECT DeviceObject,PVOID Context)
108 {
109     
110 #ifdef _WIN64
111     InlineHookSSDTWin7_X64((ULONG64)Old_NtOpenProcess,(ULONG64)Fake_NtOpenProcess,14);
112 #else 
113     InlineHookSSDTWinXP_X86((ULONG32)Old_NtOpenProcess,(ULONG32)Fake_NtOpenProcess,5);
114 #endif
115     
116 
117 
118 
119 
120 }
121 
122 VOID  UnloadDriver(PDRIVER_OBJECT DriverObject)
123 {
124 
125 
126     IoStopTimer(DriverObject->DeviceObject);
127     if (DriverObject->DeviceObject!=NULL)
128     {
129         IoDeleteDevice(DriverObject->DeviceObject);
130     }
131 
132 #ifdef _WIN64
133 
134     UnInlineHookSSDTWin7_X64((ULONG64)Old_NtOpenProcess,(ULONG64)Old_NtOpenProcessHeaderBytes,14);
135 
136 
137     if (Old_NtOpenProcessHeaderBytes!=NULL)
138     {
139         ExFreePool(Old_NtOpenProcessHeaderBytes);
140         Old_NtOpenProcessHeaderBytes = NULL;
141     }
142 
143     if (NtOpenProcessPassCode!=NULL)
144     {
145         ExFreePool(NtOpenProcessPassCode);
146         NtOpenProcessPassCode = NULL;
147     }
148 #else
149 
150     UnInlineHookSSDTWinXP_X86((ULONG32)Old_NtOpenProcess,(ULONG32)Old_NtOpenProcessHeaderBytes,5);
151 
152 
153     if (Old_NtOpenProcessHeaderBytes!=NULL)
154     {
155         ExFreePool(Old_NtOpenProcessHeaderBytes);
156         Old_NtOpenProcessHeaderBytes = NULL;
157     }
158 
159     if (NtOpenProcessPassCode!=NULL)
160     {
161         ExFreePool(NtOpenProcessPassCode);
162         NtOpenProcessPassCode = NULL;
163     }
164 #endif
165 
166 
167 
168 }
169 
170 BOOLEAN GetSSDTAddressInWinXP_X86(ULONG32* SSDTAddress)
171 {
172     //从NtosKernel.exe 模块中的导出表获得该导出变量  KeServiceDescriptorTable
173 
174     /*
175     kd> dd KeServiceDescriptorTable
176     80563520  804e58a0 00000000 0000011c 805120bc
177     */
178     *SSDTAddress = NULL;
179     *SSDTAddress = (ULONG32)GetExportVariableAddressFormNtosExportTableByVariableName(L"KeServiceDescriptorTable");
180 
181     if (*SSDTAddress!=NULL)
182     {
183         return TRUE;
184     }
185 
186     return FALSE;
187 }
188 
189 
190 PVOID 
191     GetExportVariableAddressFormNtosExportTableByVariableName(WCHAR *wzVariableName)
192 {
193     UNICODE_STRING uniVariableName;  
194     PVOID VariableAddress = NULL;
195 
196     if (wzVariableName && wcslen(wzVariableName) > 0)
197     {
198         RtlInitUnicodeString(&uniVariableName, wzVariableName);  
199 
200         //从Ntos模块的导出表中获得一个导出变量的地址
201         VariableAddress = MmGetSystemRoutineAddress(&uniVariableName); 
202     }
203 
204     return VariableAddress;
205 }
206 
207 
208 
209 
210 VOID UnInlineHookSSDTWinXP_X86(ULONG32 ulCurrentVariable,ULONG32 ulOldVariable,ULONG32 ulPatchSize)
211 {
212     WPOFF();
213     memcpy((PVOID)ulCurrentVariable,(PVOID)ulOldVariable,ulPatchSize);  
214     WPON();
215 }
216 
217 
218 BOOLEAN InlineHookSSDTWinXP_X86(ULONG32 ulOldVariable,ULONG32 ulFakeVariable,ULONG32 ulPatchSize)
219 {
220     UCHAR v1[] = "xe9x00x00x00x00";
221     UCHAR v2[] = "xe9x00x00x00x00";
222     ULONG32 ulTemp = 0;
223 
224     /*
225     kd> u 8058270A
226     nt!NtOpenProcess:
227     8058270a 68c4000000      push    0C4h
228     8058270f 68d8524f80      push    offset nt!ObWatchHandles+0x25c (804f52d8)
229     80582714 e85a17f6ff      call    nt!_SEH_prolog (804e3e73)
230     80582719 33f6            xor     esi,esi
231     8058271b 8975d4          mov     dword ptr [ebp-2Ch],esi
232     8058271e 33c0            xor     eax,eax
233     80582720 8d7dd8          lea     edi,[ebp-28h]
234     80582723 ab              stos    dword ptr es:[edi]
235     */
236 
237 
238 
239     Old_NtOpenProcessHeaderBytes = ExAllocatePool(NonPagedPool,ulPatchSize); 
240 
241     if (Old_NtOpenProcessHeaderBytes==NULL)
242     {
243         return FALSE;
244     }
245 
246 
247     WPOFF();
248     memcpy(Old_NtOpenProcessHeaderBytes,(PVOID)ulOldVariable,ulPatchSize);
249     //    Old_NtOpenProcessHeaderBytes[   68c4000000      ]
250     WPON();
251 
252 
253 
254     NtOpenProcessPassCode = ExAllocatePool(NonPagedPool,(ulPatchSize+5));
255     if (NtOpenProcessPassCode==NULL)
256     {
257 
258         if (Old_NtOpenProcessHeaderBytes!=NULL)
259         {
260             ExFreePool(Old_NtOpenProcessHeaderBytes);
261             Old_NtOpenProcessHeaderBytes = NULL;
262         }
263         return FALSE;
264     }
265 
266     
267 
268     RtlFillMemory(NtOpenProcessPassCode,ulPatchSize+5,0x90);  //NOP
269     //NtOpenProcessPassCode[0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90]
270 
271 
272     memcpy((PUCHAR)NtOpenProcessPassCode,Old_NtOpenProcessHeaderBytes,ulPatchSize);  
273     //NtOpenProcessPassCode[ 68c4000000 0x90 0x90 0x90 0x90 0x90]
274 
275 
276     ulTemp=(ULONG32)ulOldVariable+ulPatchSize;       
277     //8058270a  + 5  = 8058270f   = ulTemp                  
278 
279     *((ULONG32*)&v2[1]) = (ULONG32)ulTemp  - ((ULONG32)NtOpenProcessPassCode +5 + 5); //第一个+5 是过前5个字节 第二个加 是 新 - (旧+5)
280 
281     memcpy((PUCHAR)NtOpenProcessPassCode+ulPatchSize,v2,5);
282 
283 
284     ulTemp = (ULONG32)ulFakeVariable;
285 
286     *((ULONG32*)&v1[1]) = (ULONG32)ulTemp  - ((ULONG32)ulOldVariable +5); 
287 
288     WPOFF();
289     RtlFillMemory((PVOID)ulOldVariable,ulPatchSize,0x90);
290     memcpy((PVOID)ulOldVariable,v1,5);
291     WPON();
292 
293     return TRUE;
294 }
295 
296 
297 
298 BOOLEAN GetSSDTAddressInWin7_X64(ULONG64* SSDTAddress)
299 {
300 
301     
302     /*
303     kd> rdmsr c0000082 
304     msr[c0000082] = fffff800`03ecf640
305     kd> u fffff800`03ecf640 l 50
306     nt!KiSystemCall64:
307     fffff800`03ecf640 0f01f8          swapgs
308     fffff800`03ecf643 654889242510000000 mov   qword ptr gs:[10h],rsp
309     fffff800`03ecf64c 65488b2425a8010000 mov   rsp,qword ptr gs:[1A8h]
310     fffff800`03ecf655 6a2b            push    2Bh
311     fffff800`03ecf657 65ff342510000000 push    qword ptr gs:[10h]
312     fffff800`03ecf65f 4153            push    r11
313     fffff800`03ecf661 6a33            push    33h
314     fffff800`03ecf663 51              push    rcx
315     fffff800`03ecf664 498bca          mov     rcx,r10
316     fffff800`03ecf667 4883ec08        sub     rsp,8
317     fffff800`03ecf66b 55              push    rbp
318     fffff800`03ecf66c 4881ec58010000  sub     rsp,158h
319     fffff800`03ecf673 488dac2480000000 lea     rbp,[rsp+80h]
320     fffff800`03ecf67b 48899dc0000000  mov     qword ptr [rbp+0C0h],rbx
321     fffff800`03ecf682 4889bdc8000000  mov     qword ptr [rbp+0C8h],rdi
322     fffff800`03ecf689 4889b5d0000000  mov     qword ptr [rbp+0D0h],rsi
323     fffff800`03ecf690 c645ab02        mov     byte ptr [rbp-55h],2
324     fffff800`03ecf694 65488b1c2588010000 mov   rbx,qword ptr gs:[188h]
325     fffff800`03ecf69d 0f0d8bd8010000  prefetchw [rbx+1D8h]
326     fffff800`03ecf6a4 0fae5dac        stmxcsr dword ptr [rbp-54h]
327     fffff800`03ecf6a8 650fae142580010000 ldmxcsr dword ptr gs:[180h]
328     fffff800`03ecf6b1 807b0300        cmp     byte ptr [rbx+3],0
329     fffff800`03ecf6b5 66c785800000000000 mov   word ptr [rbp+80h],0
330     fffff800`03ecf6be 0f848c000000    je      nt!KiSystemCall64+0x110 (fffff800`03ecf750)
331     fffff800`03ecf6c4 488945b0        mov     qword ptr [rbp-50h],rax
332     fffff800`03ecf6c8 48894db8        mov     qword ptr [rbp-48h],rcx
333     fffff800`03ecf6cc 488955c0        mov     qword ptr [rbp-40h],rdx
334     fffff800`03ecf6d0 f6430303        test    byte ptr [rbx+3],3
335     fffff800`03ecf6d4 4c8945c8        mov     qword ptr [rbp-38h],r8
336     fffff800`03ecf6d8 4c894dd0        mov     qword ptr [rbp-30h],r9
337     fffff800`03ecf6dc 7405            je      nt!KiSystemCall64+0xa3 (fffff800`03ecf6e3)
338     fffff800`03ecf6de e80d140000      call    nt!KiSaveDebugRegisterState (fffff800`03ed0af0)
339     fffff800`03ecf6e3 f6430380        test    byte ptr [rbx+3],80h
340     fffff800`03ecf6e7 7442            je      nt!KiSystemCall64+0xeb (fffff800`03ecf72b)
341     fffff800`03ecf6e9 b9020100c0      mov     ecx,0C0000102h
342     fffff800`03ecf6ee 0f32            rdmsr
343     fffff800`03ecf6f0 48c1e220        shl     rdx,20h
344     fffff800`03ecf6f4 480bc2          or      rax,rdx
345     fffff800`03ecf6f7 483983b8000000  cmp     qword ptr [rbx+0B8h],rax
346     fffff800`03ecf6fe 742b            je      nt!KiSystemCall64+0xeb (fffff800`03ecf72b)
347     fffff800`03ecf700 483983b0010000  cmp     qword ptr [rbx+1B0h],rax
348     fffff800`03ecf707 7422            je      nt!KiSystemCall64+0xeb (fffff800`03ecf72b)
349     fffff800`03ecf709 488b93b8010000  mov     rdx,qword ptr [rbx+1B8h]
350     fffff800`03ecf710 0fba6b4c0b      bts     dword ptr [rbx+4Ch],0Bh
351     fffff800`03ecf715 66ff8bc4010000  dec     word ptr [rbx+1C4h]
352     fffff800`03ecf71c 48898280000000  mov     qword ptr [rdx+80h],rax
353     fffff800`03ecf723 fb              sti
354     fffff800`03ecf724 e8170b0000      call    nt!KiUmsCallEntry (fffff800`03ed0240)
355     fffff800`03ecf729 eb0f            jmp     nt!KiSystemCall64+0xfa (fffff800`03ecf73a)
356     fffff800`03ecf72b f6430340        test    byte ptr [rbx+3],40h
357     fffff800`03ecf72f 7409            je      nt!KiSystemCall64+0xfa (fffff800`03ecf73a)
358     fffff800`03ecf731 f00fbaab0001000008 lock bts dword ptr [rbx+100h],8
359     fffff800`03ecf73a 488b45b0        mov     rax,qword ptr [rbp-50h]
360     fffff800`03ecf73e 488b4db8        mov     rcx,qword ptr [rbp-48h]
361     fffff800`03ecf742 488b55c0        mov     rdx,qword ptr [rbp-40h]
362     fffff800`03ecf746 4c8b45c8        mov     r8,qword ptr [rbp-38h]
363     fffff800`03ecf74a 4c8b4dd0        mov     r9,qword ptr [rbp-30h]
364     fffff800`03ecf74e 6690            xchg    ax,ax
365     fffff800`03ecf750 fb              sti
366     fffff800`03ecf751 48898be0010000  mov     qword ptr [rbx+1E0h],rcx
367     fffff800`03ecf758 8983f8010000    mov     dword ptr [rbx+1F8h],eax
368     nt!KiSystemServiceStart:
369     fffff800`03ecf75e 4889a3d8010000  mov     qword ptr [rbx+1D8h],rsp
370     fffff800`03ecf765 8bf8            mov     edi,eax
371     fffff800`03ecf767 c1ef07          shr     edi,7
372     fffff800`03ecf76a 83e720          and     edi,20h
373     fffff800`03ecf76d 25ff0f0000      and     eax,0FFFh
374     nt!KiSystemServiceRepeat:
375     fffff800`03ecf772 4c8d15c7202300  lea     r10,[nt!KeServiceDescriptorTable (fffff800`04101840)]
376 
377     fffff800`03ecf772 + 002320c7 + 7  = fffff800`04101840
378     */
379 
380 
381 
382 
383     PUCHAR StartSearchAddress = (PUCHAR)__readmsr(0xC0000082);   //fffff800`03ecf640
384     PUCHAR EndSearchAddress = StartSearchAddress + 0x500;
385     PUCHAR i = NULL;
386     UCHAR   v1=0,v2=0,v3=0;
387     INT64   iOffset = 0;    //002320c7
388     ULONG64 VariableAddress = 0;
389     *SSDTAddress = NULL;
390     for(i=StartSearchAddress;i<EndSearchAddress;i++)
391     {
392         if( MmIsAddressValid(i) && MmIsAddressValid(i+1) && MmIsAddressValid(i+2) )
393         {
394             v1=*i;
395             v2=*(i+1);
396             v3=*(i+2);
397             if(v1==0x4c && v2==0x8d && v3==0x15 ) 
398             {
399                 memcpy(&iOffset,i+3,4);
400                 *SSDTAddress = iOffset + (ULONG64)i + 7;
401 
402                 break;
403             }
404         }
405     }
406 
407     if (*SSDTAddress==NULL)
408     {
409         return FALSE;
410     }
411 
412     /*
413     kd> dq fffff800`04101840
414     fffff800`04101840  fffff800`03ed1300 00000000`00000000
415     fffff800`04101850  00000000`00000191 fffff800`03ed1f8c
416 
417     */
418     return TRUE;
419 }
420 
421 
422 BOOLEAN GetSSDTFunctionIndexFromNtdllExportTableByFunctionNameInWin7_X64(CHAR* szFindFunctionName,ULONG32* SSDTFunctionIndex)
423 {
424     /*
425     0:004> u zwopenprocess
426     ntdll!NtOpenProcess:
427     00000000`774ddc10 4c8bd1          mov     r10,rcx
428     00000000`774ddc13 b823000000      mov     eax,23h
429     00000000`774ddc18 0f05            syscall
430     00000000`774ddc1a c3              ret
431     00000000`774ddc1b 0f1f440000      nop     dword ptr [rax+rax]
432     */
433 
434     ULONG32     ulOffset_SSDTFunctionIndex = 4;
435 
436     ULONG   i;
437     BOOLEAN  bOk = FALSE;
438     WCHAR    wzFileFullPath[] = L"\SystemRoot\System32\ntdll.dll";
439     SIZE_T   MappingViewSize   = 0;
440     PVOID    MappingBaseAddress = NULL;
441     PIMAGE_NT_HEADERS  NtHeader = NULL;
442     PIMAGE_EXPORT_DIRECTORY ExportDirectory = NULL;
443     ULONG32*  AddressOfFunctions    = NULL;
444     ULONG32*  AddressOfNames        = NULL;
445     USHORT*   AddressOfNameOrdinals = NULL;
446     CHAR*     szFunctionName        = NULL;
447     ULONG32   ulFunctionOrdinal     = 0;
448     ULONG64   ulFunctionAddress     = 0;
449 
450     *SSDTFunctionIndex = -1;
451 
452 
453     //将Ntdll.dll 当前的空间中
454     bOk = MappingPEFileInRing0Space(wzFileFullPath,&MappingBaseAddress, &MappingViewSize);
455     if (bOk==FALSE)
456     {
457         return FALSE;
458     }
459     else
460     {
461         __try{
462             NtHeader = RtlImageNtHeader(MappingBaseAddress);
463             if (NtHeader && NtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress)
464             {
465                 ExportDirectory =(IMAGE_EXPORT_DIRECTORY*)((ULONG64)MappingBaseAddress + NtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
466 
467 
468 
469                 AddressOfFunctions = (ULONG32*)((ULONG64)MappingBaseAddress + ExportDirectory->AddressOfFunctions);
470                 AddressOfNames = (ULONG32*)((ULONG64)MappingBaseAddress + ExportDirectory->AddressOfNames);
471                 AddressOfNameOrdinals = (USHORT*)((ULONG64)MappingBaseAddress + ExportDirectory->AddressOfNameOrdinals);
472                 for(i = 0; i < ExportDirectory->NumberOfNames; i++)
473                 {
474                     szFunctionName = (char*)((ULONG64)MappingBaseAddress + AddressOfNames[i]);   //获得函数名称
475                     if (_stricmp(szFunctionName, szFindFunctionName) == 0)   
476                     {
477                         ulFunctionOrdinal = AddressOfNameOrdinals[i]; 
478                         ulFunctionAddress = (ULONG64)((ULONG64)MappingBaseAddress + AddressOfFunctions[ulFunctionOrdinal]);
479 
480 
481                         *SSDTFunctionIndex = *(ULONG32*)(ulFunctionAddress+ulOffset_SSDTFunctionIndex); 
482                         break;
483                     }
484                 }
485             }
486         }__except(EXCEPTION_EXECUTE_HANDLER)
487         {
488             ;
489         }
490     }
491 
492 
493     ZwUnmapViewOfSection(NtCurrentProcess(), MappingBaseAddress);
494 
495 
496     if (*SSDTFunctionIndex==-1)
497     {
498         return FALSE;
499     }
500 
501     return TRUE;
502 }
503 
504 
505 VOID UnInlineHookSSDTWin7_X64(ULONG64 ulCurrentVariable,ULONG64 ulOldVariable,ULONG32 ulPatchSize)
506 {
507     WPOFF();
508     memcpy((PVOID)ulCurrentVariable,(PVOID)ulOldVariable,ulPatchSize);  
509     WPON();
510 }
511 
512 
513 BOOLEAN InlineHookSSDTWin7_X64(ULONG64 ulOldVariable,ULONG64 ulFakeVariable,ULONG32 ulPatchSize)
514 {
515     UCHAR v1[]="xFFx25x00x00x00x00xFFxFFxFFxFFxFFxFFxFFxFF";
516     UCHAR v2[]="xFFx25x00x00x00x00xFFxFFxFFxFFxFFxFFxFFxFF";
517     ULONG64 ulTemp = 0;
518 
519     //保存这14个字节的内容
520     Old_NtOpenProcessHeaderBytes = ExAllocatePool(NonPagedPool,ulPatchSize);
521 
522     if (Old_NtOpenProcessHeaderBytes==NULL)
523     {
524         return FALSE;
525     }
526     WPOFF();
527     memcpy(Old_NtOpenProcessHeaderBytes,(PVOID)ulOldVariable,ulPatchSize);
528     WPON();
529 
530 
531     //构建保存原先的前14个字节的内容和跳转到14个字节之后的指令的内容
532     NtOpenProcessPassCode = ExAllocatePool(NonPagedPool,(ulPatchSize+14));     
533     if (NtOpenProcessPassCode==NULL)
534     {
535         ExFreePool(Old_NtOpenProcessHeaderBytes);
536         Old_NtOpenProcessHeaderBytes = NULL;
537         return FALSE;
538     }
539 
540     RtlFillMemory(NtOpenProcessPassCode,ulPatchSize+14,0x90);//NOP
541 
542     memcpy((PUCHAR)NtOpenProcessPassCode,Old_NtOpenProcessHeaderBytes,ulPatchSize);   //保存原先的14个字节
543 
544     ulTemp=(ULONG64)ulOldVariable+ulPatchSize;                             //原先函数14个字节之后的内容所在的地址    Temp = 0x12345678
545 
546     memcpy(v2+6,&ulTemp,8);                                    //构建跳转到该地址的Shell
547 
548     memcpy((PUCHAR)NtOpenProcessPassCode+ulPatchSize,v2,ulPatchSize);           //保存
549 
550 
551 
552 
553     //构建跳转到我们Fake函数的Shell
554     ulTemp = (ULONG64)ulFakeVariable;
555     memcpy(v1+6,&ulTemp,8);
556 
557 
558 
559     //修改原先的14个字节为跳转到Fake的指令
560     WPOFF();
561     RtlFillMemory((PVOID)ulOldVariable,ulPatchSize,0x90);
562     memcpy((PVOID)ulOldVariable,v1,ulPatchSize);
563     WPON();
564 }
565 
566 
567 
568 VOID WPOFF()
569 {
570     //选择性编译,是给编译器看的
571 #if (defined(_M_AMD64) || defined(_M_IA64)) && !defined(_REALLY_GET_CALLERS_CALLER_)
572     _disable();
573     __writecr0(__readcr0() & (~(0x10000)));
574 #else
575     __asm
576     {
577         CLI  ;                 
578         MOV    EAX, CR0;    
579         AND    EAX, NOT 10000H;
580         MOV    CR0, EAX;        
581     }
582 #endif
583 }
584 VOID WPON()
585 {
586 #if (defined(_M_AMD64) || defined(_M_IA64)) && !defined(_REALLY_GET_CALLERS_CALLER_)
587     __writecr0(__readcr0() ^ 0x10000);
588     _enable();
589 #else
590     __asm
591     {
592         MOV    EAX, CR0;        
593         OR     EAX, 10000H;            
594         MOV    CR0, EAX;              
595         STI;                    
596     }
597 #endif
598 }
599 
600 
601 
602 BOOLEAN GetSSDTFunctionIndexFromNtdllExportTableByFunctionNameInWinXP_X86(CHAR* szFindFunctionName,
603     ULONG32* SSDTFunctionIndex)
604 {
605     /*
606     0:001> u zwopenprocess
607     ntdll!ZwOpenProcess:
608     7c92d5e0 b87a000000      mov     eax,7Ah
609     7c92d5e5 ba0003fe7f      mov     edx,offset SharedUserData!SystemCallStub (7ffe0300)
610     7c92d5ea ff12            call    dword ptr [edx]
611     7c92d5ec c21000          ret     10h
612     7c92d5ef 90              nop
613     */
614 
615     ULONG32     ulOffset_SSDTFunctionIndex = 1;
616 
617 
618     //从Ntdll模块的导出表中获得7c92d5e0
619     //使用内存映射将Ntdll模块映射到System进程的内存空间进行查找(Ntdll.dll模块的导出表中进行搜索)
620     ULONG   i;
621     BOOLEAN  bOk = FALSE;
622     WCHAR    wzFileFullPath[] = L"\SystemRoot\System32\ntdll.dll";
623     SIZE_T  MappingViewSize   = 0;
624     PVOID    MappingBaseAddress = NULL;
625     PIMAGE_NT_HEADERS  NtHeader = NULL;
626     PIMAGE_EXPORT_DIRECTORY ExportDirectory = NULL;
627     ULONG32*  AddressOfFunctions    = NULL;
628     ULONG32*  AddressOfNames        = NULL;
629     USHORT* AddressOfNameOrdinals = NULL;
630     CHAR*   szFunctionName        = NULL;
631     ULONG32 ulFunctionOrdinal     = 0;
632     ULONG32 ulFunctionAddress     = 0;
633     
634     *SSDTFunctionIndex = -1;
635 
636 
637     //将Ntdll.dll 当前的空间中
638     bOk = MappingPEFileInRing0Space(wzFileFullPath,&MappingBaseAddress, &MappingViewSize);
639     if (bOk==FALSE)
640     {
641         return FALSE;
642     }
643     else
644     {
645         __try{
646             NtHeader = RtlImageNtHeader(MappingBaseAddress);
647             if (NtHeader && NtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress)
648             {
649                 ExportDirectory =(IMAGE_EXPORT_DIRECTORY*)((ULONG32)MappingBaseAddress + NtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
650                 
651                 
652                 
653                 AddressOfFunctions = (ULONG32*)((ULONG32)MappingBaseAddress + ExportDirectory->AddressOfFunctions);
654                 AddressOfNames = (ULONG32*)((ULONG32)MappingBaseAddress + ExportDirectory->AddressOfNames);
655                 AddressOfNameOrdinals = (USHORT*)((ULONG32)MappingBaseAddress + ExportDirectory->AddressOfNameOrdinals);
656                 for(i = 0; i < ExportDirectory->NumberOfNames; i++)
657                 {
658                     szFunctionName = (char*)((ULONG32)MappingBaseAddress + AddressOfNames[i]);   //获得函数名称
659                     if (_stricmp(szFunctionName, szFindFunctionName) == 0)   
660                     {
661                         ulFunctionOrdinal = AddressOfNameOrdinals[i]; 
662                         ulFunctionAddress = (ULONG32)((ULONG32)MappingBaseAddress + AddressOfFunctions[ulFunctionOrdinal]);
663                         
664                         
665                         *SSDTFunctionIndex = *(ULONG32*)(ulFunctionAddress+ulOffset_SSDTFunctionIndex); 
666                         break;
667                     }
668                 }
669             }
670         }__except(EXCEPTION_EXECUTE_HANDLER)
671         {
672             ;
673         }
674     }
675 
676 
677     ZwUnmapViewOfSection(NtCurrentProcess(), MappingBaseAddress);
678 
679 
680     if (*SSDTFunctionIndex==-1)
681     {
682         return FALSE;
683     }
684     
685     return TRUE;
686 }
687 
688 BOOLEAN 
689     MappingPEFileInRing0Space(WCHAR* wzFileFullPath,OUT PVOID* MappingBaseAddress,PSIZE_T MappingViewSize)
690 {
691     UNICODE_STRING    uniFileFullPath;
692     OBJECT_ATTRIBUTES oa;
693     NTSTATUS          Status;
694     IO_STATUS_BLOCK   Iosb;
695 
696     HANDLE   hFile = NULL;
697     HANDLE   hSection = NULL;
698 
699     if (!wzFileFullPath || !MappingBaseAddress){
700         return FALSE;
701     }
702 
703     RtlInitUnicodeString(&uniFileFullPath, wzFileFullPath);
704     InitializeObjectAttributes(&oa,
705         &uniFileFullPath,
706         OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
707         NULL,
708         NULL
709         );
710 
711 
712     //获得文件句柄
713     Status = IoCreateFile(&hFile,
714         GENERIC_READ | SYNCHRONIZE,
715         &oa,   //文件绝对路径
716         &Iosb,
717         NULL,
718         FILE_ATTRIBUTE_NORMAL,
719         FILE_SHARE_READ,
720         FILE_OPEN,
721         FILE_SYNCHRONOUS_IO_NONALERT,
722         NULL,
723         0,
724         CreateFileTypeNone,
725         NULL,
726         IO_NO_PARAMETER_CHECKING
727         );
728     if (!NT_SUCCESS(Status))
729     {
730 
731         return FALSE;
732     }
733 
734     oa.ObjectName = NULL;
735     Status = ZwCreateSection(&hSection,
736         SECTION_QUERY | SECTION_MAP_READ,
737         &oa,
738         NULL,
739         PAGE_WRITECOPY,
740         SEC_IMAGE,  //??  指示内存对齐
741         hFile
742         );
743     ZwClose(hFile);
744     if (!NT_SUCCESS(Status))
745     {
746 
747         return FALSE;
748     }
749     Status = ZwMapViewOfSection(hSection, 
750         NtCurrentProcess(),    //映射到当前进程的内存空间中
751         MappingBaseAddress, 
752         0, 
753         0, 
754         0, 
755         MappingViewSize, 
756         ViewUnmap, 
757         0, 
758         PAGE_WRITECOPY
759         );
760     ZwClose(hSection);
761     if (!NT_SUCCESS(Status))
762     {
763         return FALSE;
764     }
765 
766     return TRUE;
767 }
768 
769 
770 
771 NTSTATUS Fake_NtOpenProcess(
772     PHANDLE ProcessHandle,
773     ACCESS_MASK DesiredAccess,
774     POBJECT_ATTRIBUTES ObjectAttributes,PCLIENT_ID ClientId)
775 {
776     PEPROCESS  EProcess = PsGetCurrentProcess();    //进程上下背景文
777     if (EProcess!=NULL)
778     {
779         //通过EProcess 获得进程名称 
780 
781         char *szProcessImageName = PsGetProcessImageFileName(EProcess);
782 
783         if (strstr(szProcessImageName,"EnumProcess")!=0)
784         {
785 
786             return STATUS_ACCESS_DENIED;
787         }
788     }
789 
790     if (NtOpenProcessPassCode!=NULL)
791     {
792         ((pfnNtOpenProcess)NtOpenProcessPassCode)(ProcessHandle,DesiredAccess,ObjectAttributes,ClientId);
793     }
794 }
View Code
 1 /***************************************************************************************
 2 * AUTHOR : 
 3 * DATE   : 2015-11-1
 4 * MODULE : IoTimerInlineHook.H
 5 *
 6 * IOCTRL Sample Driver
 7 *
 8 * Description:
 9 *        Demonstrates communications between USER and KERNEL.
10 *
11 ****************************************************************************************
12 * Copyright (C) 2010 .
13 ****************************************************************************************/
14 
15 #ifndef CXX_IOTIMERINLINEHOOK_H
16 #define CXX_IOTIMERINLINEHOOK_H
17 
18 
19 
20 #include <ntifs.h>
21 
22 #include <ntimage.h>
23 #define DEVICE_NAME   L"\Device\IoTimerInlineHookDeviceName"
24 
25 #define SEC_IMAGE  0x01000000
26 
27 //定义SSDT表的结构
28 typedef struct _SYSTEM_SERVICE_TABLE_WIN7_X64{
29     PVOID          ServiceTableBase; 
30     PVOID          ServiceCounterTableBase; 
31     ULONG64      NumberOfServices;                     //SSDT表中的函数个数   0x191
32     PVOID          ParamTableBase; 
33 } SYSTEM_SERVICE_TABLE_WIN7_X64, *PSYSTEM_SERVICE_TABLE_WIN7_X64;
34 
35 typedef struct _SYSTEM_SERVICE_TABLE_WINXP_X86 {
36     PVOID   ServiceTableBase;
37     PVOID   ServiceCounterTableBase;
38     ULONG32 NumberOfServices;                         //SSDT表中的函数个数   0x11c
39     PVOID   ParamTableBase;
40 } SYSTEM_SERVICE_TABLE_WINXP_X86, *PSYSTEM_SERVICE_TABLE_WINXP_X86;
41 
42 extern
43     char* PsGetProcessImageFileName(PEPROCESS EProcess);
44 
45 extern
46     PIMAGE_NT_HEADERS
47     NTAPI
48     RtlImageNtHeader(PVOID BaseAddress);
49 
50 typedef
51     NTSTATUS
52     (*pfnNtOpenProcess)(
53     PHANDLE ProcessHandle,
54     ACCESS_MASK DesiredAccess,
55     POBJECT_ATTRIBUTES ObjectAttributes,PCLIENT_ID ClientId);
56 
57 NTSTATUS Fake_NtOpenProcess(
58     PHANDLE ProcessHandle,
59     ACCESS_MASK DesiredAccess,
60     POBJECT_ATTRIBUTES ObjectAttributes,PCLIENT_ID ClientId);
61 
62 
63 #ifdef _WIN64
64 #define PSYSTEM_SERVICE_TABLE PSYSTEM_SERVICE_TABLE_WIN7_X64    
65 #else
66 #define PSYSTEM_SERVICE_TABLE PSYSTEM_SERVICE_TABLE_WINXP_X86   
67 #endif
68 
69 VOID  UnloadDriver(PDRIVER_OBJECT DriverObject);
70 
71 
72 BOOLEAN GetSSDTAddressInWinXP_X86(ULONG32* SSDTAddress);
73 BOOLEAN GetSSDTFunctionIndexFromNtdllExportTableByFunctionNameInWinXP_X86(CHAR* szFindFunctionName,
74     ULONG32* SSDTFunctionIndex);
75 BOOLEAN InlineHookSSDTWinXP_X86(ULONG32 ulOldVariable,ULONG32 ulFakeVariable,ULONG32 ulPatchSize);
76 VOID UnInlineHookSSDTWinXP_X86(ULONG32 ulCurrentVariable,ULONG32 ulOldVariable,ULONG32 ulPatchSize);
77 
78 
79 BOOLEAN GetSSDTAddressInWin7_X64(ULONG64* SSDTAddress);
80 BOOLEAN GetSSDTFunctionIndexFromNtdllExportTableByFunctionNameInWin7_X64(CHAR* szFindFunctionName,ULONG32* SSDTFunctionIndex);
81 BOOLEAN InlineHookSSDTWin7_X64(ULONG64 ulOldVariable,ULONG64 ulFakeVariable,ULONG32 ulPatchSize);
82 VOID UnInlineHookSSDTWin7_X64(ULONG64 ulCurrentVariable,ULONG64 ulOldVariable,ULONG32 ulPatchSize);
83 
84 PVOID 
85     GetExportVariableAddressFormNtosExportTableByVariableName(WCHAR *wzVariableName);
86 
87 BOOLEAN 
88     MappingPEFileInRing0Space(WCHAR* wzFileFullPath,OUT PVOID* MappingBaseAddress,PSIZE_T MappingViewSize);
89 
90 
91 
92 VOID WPOFF();
93 VOID WPON();
94 
95 VOID
96     CallBackProcedure(PDEVICE_OBJECT DeviceObject,PVOID Context);
97 
98 
99 #endif    
View Code
爱程序 不爱bug 爱生活 不爱黑眼圈 我和你们一样 我和你们不一样 我不是凡客 我要做geek
原文地址:https://www.cnblogs.com/yifi/p/4953165.html