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 }