1 了解PE结构
2 懂HOOK KiFastCallEntry
3 理解SSDT表 (需要修复SSDT表)
其实操作不算太复杂, 需要有一定的基础
完整测试的实例代码
001 | #include <ntddk.h> |
002 | #include "ntimage.h" |
003 | #define __Max(a,b) a>b?a:b |
004 |
005 | #pragma pack(1) |
006 | typedef struct ServiceDescriptorEntry { |
007 | unsigned int *ServiceTableBase; |
008 | unsigned int *ServiceCounterTableBase; //仅适用于checked build版本 |
009 | unsigned int NumberOfServices; |
010 | unsigned char *ParamTableBase; |
011 | } ServiceDescriptorTableEntry_t, *PServiceDescriptorTableEntry_t; |
012 | #pragma pack() |
013 |
014 | __declspec ( dllimport ) ServiceDescriptorTableEntry_t KeServiceDescriptorTable; |
015 |
016 | typedef struct _LDR_DATA_TABLE_ENTRY{ |
017 | LIST_ENTRY InLoadOrderLinks; |
018 | LIST_ENTRY InMemoryOrderLinks; |
019 | LIST_ENTRY InInitializationOrderLinks; |
020 | PVOID DllBase; |
021 | PVOID EntryPoint; |
022 | ULONG SizeOfImage; |
023 | UNICODE_STRING FullDllName; |
024 | UNICODE_STRING BaseDllName; |
025 | ULONG Flags; |
026 | USHORT LoadCount; |
027 | USHORT TlsIndex; |
028 | union |
029 | { |
030 | LIST_ENTRY HashLinks; |
031 | struct |
032 | { |
033 | PVOID SectionPointer; |
034 | ULONG CheckSum; |
035 | }; |
036 | }; |
037 | union |
038 | { |
039 | ULONG TimeDateStamp; |
040 | PVOID LoadedImports; |
041 | }; |
042 | PVOID EntryPointActivationContext; |
043 | PVOID PatchInformation; |
044 | } LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY; |
045 |
046 |
047 |
048 | typedef NTSTATUS |
049 | (*NTCREATEFILE) ( |
050 | __out PHANDLE FileHandle, |
051 | __in ACCESS_MASK DesiredAccess, |
052 | __in POBJECT_ATTRIBUTES ObjectAttributes, |
053 | __out PIO_STATUS_BLOCK IoStatusBlock, |
054 | __in_opt PLARGE_INTEGER AllocationSize, |
055 | __in ULONG FileAttributes, |
056 | __in ULONG ShareAccess, |
057 | __in ULONG CreateDisposition, |
058 | __in ULONG CreateOptions, |
059 | __in_bcount_opt(EaLength) PVOID EaBuffer, |
060 | __in ULONG EaLength |
061 | ); |
062 |
063 |
064 | //全局变量的定义 |
065 | PVOID g_lpVirtualPointer = 0; |
066 | ULONG g_ntcreatefile; |
067 | ULONG g_fastcall_hookpointer; |
068 | ULONG g_goto_origfunc; |
069 | ULONG g_NewKernelInc; |
070 |
071 | ServiceDescriptorTableEntry_t *g_pNewSeviceTable; |
072 |
073 | void PageProtectOn() |
074 | { |
075 | __asm{ //恢复内存保护 |
076 | mov eax, cr0 |
077 | or eax, 10000h |
078 | mov cr0, eax |
079 | sti |
080 | } |
081 | } |
082 |
083 | void PageProtectOff() |
084 | { |
085 | __asm{ //去掉内存保护 |
086 | cli |
087 | mov eax, cr0 |
088 | and eax, not 10000h |
089 | mov cr0, eax |
090 | } |
091 | } |
092 |
093 | ULONG SearchHookPointer( ULONG StartAddress) |
094 | { |
095 | ULONG u_index; |
096 |
097 | UCHAR *p = ( UCHAR *)StartAddress; |
098 |
099 | for (u_index = 0; u_index < 200; u_index++) |
100 | { |
101 | if (*p == 0x2B && |
102 | *(p + 1) == 0xE1 && |
103 | *(p + 2) == 0xC1 && |
104 | *(p + 3) == 0xE9 && |
105 | *(p + 4) == 0x02) |
106 | { |
107 | return ( ULONG )p; |
108 | } |
109 |
110 | p--; |
111 | } |
112 |
113 | return 0; |
114 | } |
115 |
116 |
117 | ULONG FilterKiFastCallEntry( ULONG ServiceTableBase, ULONG FuncIndex, ULONG OrigFuncAddress) |
118 | { |
119 | if (ServiceTableBase == ( ULONG )KeServiceDescriptorTable.ServiceTableBase) |
120 | { |
121 | if ( strstr (( char *)PsGetCurrentProcess() + 0x174, "Ollydbg" ) != 0) |
122 | { |
123 | //用新的NtCreateFile来处理 |
124 | return g_pNewSeviceTable->ServiceTableBase[FuncIndex]; |
125 |
126 | //针对inlineHook |
127 | //return (OrigFuncAddress+g_NewKernelInc); |
128 | } |
129 | } |
130 |
131 | return OrigFuncAddress; |
132 | } |
133 |
134 | __declspec ( naked ) |
135 | void NewKiFastCallEntry() |
136 | { |
137 | __asm{ |
138 | pushad |
139 | pushfd |
140 |
141 | push edx |
142 | push eax |
143 | push edi |
144 | call FilterKiFastCallEntry |
145 |
146 | mov [esp + 0x18], eax |
147 |
148 | popfd |
149 | popad |
150 |
151 | sub esp, ecx |
152 | shr ecx, 2 |
153 | jmp g_goto_origfunc |
154 | } |
155 | } |
156 |
157 | void UnHookKiFastCallEntry() |
158 | { |
159 | UCHAR str_origfuncode[5] = { 0x2B, 0xE1, 0xC1, 0xE9, 0x02 }; |
160 |
161 | if (g_fastcall_hookpointer == 0) |
162 | { |
163 | return ; |
164 | } |
165 |
166 | PageProtectOff(); |
167 | RtlCopyMemory(( PVOID )g_fastcall_hookpointer, str_origfuncode, 5); |
168 | PageProtectOn(); |
169 | } |
170 |
171 | void HookKiFastCallEntry( ULONG HookPointer) |
172 | { |
173 | ULONG u_temp; |
174 | UCHAR str_jmp_code[5]; |
175 |
176 | str_jmp_code[0] = 0xE9; |
177 |
178 | u_temp = ( ULONG )NewKiFastCallEntry - HookPointer - 5; |
179 | *( ULONG *)&str_jmp_code[1] = u_temp; |
180 |
181 | PageProtectOff(); |
182 |
183 | RtlCopyMemory(( PVOID )HookPointer, str_jmp_code, 5); |
184 |
185 | PageProtectOn(); |
186 |
187 | } |
188 |
189 | NTSTATUS NewNtCreateFile( |
190 | __out PHANDLE FileHandle, |
191 | __in ACCESS_MASK DesiredAccess, |
192 | __in POBJECT_ATTRIBUTES ObjectAttributes, |
193 | __out PIO_STATUS_BLOCK IoStatusBlock, |
194 | __in_opt PLARGE_INTEGER AllocationSize, |
195 | __in ULONG FileAttributes, |
196 | __in ULONG ShareAccess, |
197 | __in ULONG CreateDisposition, |
198 | __in ULONG CreateOptions, |
199 | __in_bcount_opt(EaLength) PVOID EaBuffer, |
200 | __in ULONG EaLength |
201 | ) |
202 | { |
203 | ULONG u_call_retaddr; |
204 |
205 | __asm{ |
206 | pushad |
207 | mov eax, [ebp + 0x4] |
208 | mov u_call_retaddr, eax |
209 | popad |
210 | } |
211 |
212 | g_fastcall_hookpointer = SearchHookPointer(u_call_retaddr); |
213 | if (g_fastcall_hookpointer == 0) |
214 | { |
215 | KdPrint(( "search failed." )); |
216 | } |
217 | else { |
218 | KdPrint(( "search success." )); |
219 | } |
220 |
221 | g_goto_origfunc = g_fastcall_hookpointer + 5; |
222 | HookKiFastCallEntry(g_fastcall_hookpointer); |
223 |
224 | PageProtectOff(); |
225 | KeServiceDescriptorTable.ServiceTableBase[37] = (unsigned int )g_ntcreatefile; |
226 | PageProtectOn(); |
227 |
228 | return ((NTCREATEFILE)g_ntcreatefile)( |
229 | FileHandle, \ |
230 | DesiredAccess, \ |
231 | ObjectAttributes, \ |
232 | IoStatusBlock, \ |
233 | AllocationSize, \ |
234 | FileAttributes, \ |
235 | ShareAccess, \ |
236 | CreateDisposition, \ |
237 | CreateOptions, \ |
238 | EaBuffer, \ |
239 | EaLength); |
240 | } |
241 |
242 |
243 | void SearchKiFastCallEntry() |
244 | { |
245 | HANDLE hFile; |
246 | NTSTATUS Status; |
247 | OBJECT_ATTRIBUTES ObjAttr; |
248 | UNICODE_STRING usFileName; |
249 | IO_STATUS_BLOCK IoStatusBlock; |
250 |
251 | RtlInitUnicodeString(&usFileName, L "\\??\\C:\\Windows\\System32\\ntkrnlpa.exe" ); |
252 | InitializeObjectAttributes(\ |
253 | &ObjAttr, \ |
254 | &usFileName, \ |
255 | OBJ_CASE_INSENSITIVE, \ |
256 | NULL, \ |
257 | NULL); |
258 |
259 | g_ntcreatefile = KeServiceDescriptorTable.ServiceTableBase[37]; |
260 | PageProtectOff(); |
261 | KeServiceDescriptorTable.ServiceTableBase[37] = (unsigned int )NewNtCreateFile; |
262 | PageProtectOn(); |
263 |
264 | Status = ZwCreateFile(\ |
265 | &hFile, \ |
266 | FILE_ALL_ACCESS, \ |
267 | &ObjAttr, \ |
268 | &IoStatusBlock, \ |
269 | NULL, \ |
270 | FILE_ATTRIBUTE_NORMAL, \ |
271 | FILE_SHARE_READ, \ |
272 | FILE_OPEN, \ |
273 | FILE_NON_DIRECTORY_FILE, \ |
274 | NULL, \ |
275 | 0); |
276 | if (NT_SUCCESS(Status)) |
277 | { |
278 | ZwClose(hFile); |
279 | } |
280 | } |
281 |
282 |
283 | VOID SetNewSSDT(\ |
284 | PVOID pNewImage, \ |
285 | PVOID pOrigImage, \ |
286 | ServiceDescriptorTableEntry_t **pNewSeviceTable) |
287 | { |
288 | ULONG uIndex; |
289 | ULONG uNewKernelInc, uOffset; |
290 | ServiceDescriptorTableEntry_t *pNewSSDT; |
291 |
292 |
293 | uNewKernelInc = ( ULONG )pNewImage - ( ULONG )pOrigImage; |
294 | pNewSSDT = (ServiceDescriptorTableEntry_t *)(( ULONG )&KeServiceDescriptorTable + uNewKernelInc); |
295 |
296 | if (!MmIsAddressValid(pNewSSDT)) |
297 | { |
298 | KdPrint(( "pNewSSDT" )); |
299 | return ; |
300 | } |
301 |
302 | pNewSSDT->NumberOfServices = KeServiceDescriptorTable.NumberOfServices; |
303 |
304 | uOffset = ( ULONG )KeServiceDescriptorTable.ServiceTableBase - ( ULONG )pOrigImage; |
305 | pNewSSDT->ServiceTableBase = (unsigned int *)(( ULONG )pNewImage + uOffset); |
306 | if (!MmIsAddressValid(pNewSSDT->ServiceTableBase)) |
307 | { |
308 | KdPrint(( "pNewSSDT->ServiceTableBase:%X" , pNewSSDT->ServiceTableBase)); |
309 | return ; |
310 | } |
311 |
312 | for (uIndex = 0; uIndex < pNewSSDT->NumberOfServices; uIndex++) |
313 | { |
314 | pNewSSDT->ServiceTableBase[uIndex] += uNewKernelInc; |
315 | } |
316 |
317 | uOffset = ( ULONG )KeServiceDescriptorTable.ParamTableBase - ( ULONG )pOrigImage; |
318 | pNewSSDT->ParamTableBase = (unsigned char *)(( ULONG )pNewImage + uOffset); |
319 | if (!MmIsAddressValid(pNewSSDT->ParamTableBase)) |
320 | { |
321 | KdPrint(( "pNewSSDT->ParamTableBase" )); |
322 | return ; |
323 | } |
324 | RtlCopyMemory(pNewSSDT->ParamTableBase, KeServiceDescriptorTable.ParamTableBase, pNewSSDT->NumberOfServices* sizeof ( char )); |
325 |
326 | *pNewSeviceTable = pNewSSDT; |
327 | KdPrint(( "set new ssdt success." )); |
328 | } |
329 |
330 |
331 | void RelocModule( PVOID pNewImage, PVOID pOrigImage) |
332 | { |
333 | ULONG uIndex; |
334 | ULONG uRelocTableSize; |
335 | USHORT TypeValue; |
336 | USHORT *pwOffsetArrayAddress; |
337 | ULONG uTypeOffsetArraySize; |
338 | ULONG uRelocOffset; |
339 | ULONG uRelocAddress; |
340 |
341 | PIMAGE_DOS_HEADER pImageDosHeader; |
342 | PIMAGE_NT_HEADERS pImageNtHeader; |
343 | IMAGE_DATA_DIRECTORY ImageDataDirectory; |
344 | IMAGE_BASE_RELOCATION *pImageBaseRelocation; |
345 |
346 | pImageDosHeader = (PIMAGE_DOS_HEADER)pNewImage; |
347 | pImageNtHeader = (PIMAGE_NT_HEADERS)(( ULONG )pNewImage + pImageDosHeader->e_lfanew); |
348 |
349 | uRelocOffset = ( ULONG )pOrigImage - pImageNtHeader->OptionalHeader.ImageBase; |
350 | //DbgPrint("pOrigImage -- %x, uRelocOffset -- %x", pOrigImage, uRelocOffset); |
351 |
352 | ImageDataDirectory = pImageNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC]; |
353 |
354 | pImageBaseRelocation = (PIMAGE_BASE_RELOCATION)(ImageDataDirectory.VirtualAddress + ( ULONG )pNewImage); |
355 | uRelocTableSize = ImageDataDirectory.Size; |
356 |
357 | while (uRelocTableSize) |
358 | { |
359 | uTypeOffsetArraySize = (pImageBaseRelocation->SizeOfBlock - sizeof ( ULONG )* 2) / sizeof ( USHORT ); |
360 |
361 | pwOffsetArrayAddress = pImageBaseRelocation->TypeOffset; |
362 | for (uIndex = 0; uIndex < uTypeOffsetArraySize; uIndex++) |
363 | { |
364 | TypeValue = pwOffsetArrayAddress[uIndex]; |
365 | if (TypeValue >> 12 == IMAGE_REL_BASED_HIGHLOW) |
366 | { |
367 | uRelocAddress = (TypeValue & 0xfff) + pImageBaseRelocation->VirtualAddress + ( ULONG )pNewImage; |
368 | if (!MmIsAddressValid(( PVOID )uRelocAddress)) |
369 | { |
370 | continue ; |
371 | } |
372 |
373 | *( ULONG *)uRelocAddress += uRelocOffset; |
374 | } |
375 | } |
376 |
377 | uRelocTableSize -= pImageBaseRelocation->SizeOfBlock; |
378 | pImageBaseRelocation = (IMAGE_BASE_RELOCATION *)(\ |
379 | ( ULONG )pImageBaseRelocation + pImageBaseRelocation->SizeOfBlock); |
380 | } |
381 | } |
382 |
383 |
384 | NTSTATUS ReadFileToMemory( wchar_t *strFileName, PVOID *lpVirtualAddress, PVOID pOrigImage) |
385 | { |
386 | NTSTATUS Status; |
387 | LARGE_INTEGER FileOffset; |
388 | HANDLE hFile; |
389 | OBJECT_ATTRIBUTES ObjAttr; |
390 | IO_STATUS_BLOCK IoStatusBlock; |
391 | UNICODE_STRING usFileName; |
392 | IMAGE_DOS_HEADER ImageDosHeader; |
393 | IMAGE_NT_HEADERS ImageNtHeader; |
394 | IMAGE_SECTION_HEADER *pImageSectionHeader; |
395 |
396 | PVOID lpVirtualPointer; |
397 | ULONG SecVirtualAddress, SizeOfSection; |
398 | ULONG PointerToRawData; |
399 |
400 | ULONG uIndex = 0; |
401 |
402 | if (!MmIsAddressValid(strFileName)) |
403 | { |
404 | return STATUS_UNSUCCESSFUL; |
405 | } |
406 | RtlInitUnicodeString(&usFileName, strFileName); |
407 |
408 | InitializeObjectAttributes(&ObjAttr, &usFileName, OBJ_CASE_INSENSITIVE, NULL, NULL); |
409 |
410 | Status = ZwCreateFile(&hFile, FILE_ALL_ACCESS, &ObjAttr, &IoStatusBlock, |
411 | NULL, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ, FILE_OPEN, FILE_NON_DIRECTORY_FILE, |
412 | NULL, 0); |
413 |
414 | if (!NT_SUCCESS(Status)) |
415 | { |
416 | DbgPrint( "ZwCreateFile Error --- %#X" , Status); |
417 | return Status; |
418 | } |
419 | FileOffset.QuadPart = 0; |
420 | Status = ZwReadFile(hFile, NULL, NULL, NULL, |
421 | &IoStatusBlock, &ImageDosHeader, sizeof (IMAGE_DOS_HEADER), &FileOffset, NULL); |
422 |
423 | if (!NT_SUCCESS(Status)) |
424 | { |
425 | DbgPrint( "ZwReadFile ImageDosHeader Error --- %#X" , Status); |
426 | ZwClose(hFile); |
427 | return Status; |
428 | } |
429 |
430 | FileOffset.QuadPart = ImageDosHeader.e_lfanew; |
431 |
432 | Status = ZwReadFile(hFile, NULL, NULL, NULL, &IoStatusBlock, |
433 | &ImageNtHeader, sizeof (IMAGE_NT_HEADERS), &FileOffset, NULL); |
434 |
435 | if (!NT_SUCCESS(Status)) |
436 | { |
437 | DbgPrint( "ZwReadFile ImageNtHeader Error --- %#X" , Status); |
438 | ZwClose(hFile); |
439 | return Status; |
440 | } |
441 |
442 | pImageSectionHeader = ExAllocatePool(NonPagedPool, sizeof (IMAGE_SECTION_HEADER)*ImageNtHeader.FileHeader.NumberOfSections); |
443 | if (pImageSectionHeader == NULL) |
444 | { |
445 | DbgPrint( "ExAllocatePool pImageSectionHeader Error --- " ); |
446 | return STATUS_UNSUCCESSFUL; |
447 | } |
448 |
449 | FileOffset.QuadPart = ImageDosHeader.e_lfanew + sizeof (IMAGE_NT_HEADERS); |
450 | Status = ZwReadFile(hFile, NULL, NULL, NULL, &IoStatusBlock, pImageSectionHeader, |
451 | sizeof (IMAGE_SECTION_HEADER)*ImageNtHeader.FileHeader.NumberOfSections, &FileOffset, NULL); |
452 | |
453 | if (!NT_SUCCESS(Status)) |
454 | { |
455 | DbgPrint( "ZwReadFile ImageSectionHeader Error --- %#X" , Status); |
456 | ExFreePool(pImageSectionHeader); |
457 | ZwClose(hFile); |
458 | return Status; |
459 | } |
460 |
461 | lpVirtualPointer = ExAllocatePool(NonPagedPool, ImageNtHeader.OptionalHeader.SizeOfImage); |
462 | if (lpVirtualPointer == NULL) |
463 | { |
464 | DbgPrint( "ExAllocatePool Error " ); |
465 | ExFreePool(pImageSectionHeader); |
466 | ZwClose(hFile); |
467 | return STATUS_UNSUCCESSFUL; |
468 | } |
469 |
470 | memset (lpVirtualPointer, 0, ImageNtHeader.OptionalHeader.SizeOfImage); |
471 | RtlCopyMemory(lpVirtualPointer, &ImageDosHeader, sizeof (IMAGE_DOS_HEADER)); |
472 | RtlCopyMemory(( PVOID )(( ULONG )lpVirtualPointer+ImageDosHeader.e_lfanew), |
473 | &ImageNtHeader, |
474 | sizeof (IMAGE_NT_HEADERS)); |
475 | RtlCopyMemory(( PVOID )(( ULONG )lpVirtualPointer + ImageDosHeader.e_lfanew + sizeof (IMAGE_NT_HEADERS)), |
476 | pImageSectionHeader, sizeof (IMAGE_SECTION_HEADER)*ImageNtHeader.FileHeader.NumberOfSections); |
477 |
478 | for (uIndex = 0; uIndex < ImageNtHeader.FileHeader.NumberOfSections; uIndex++) |
479 | { |
480 | SecVirtualAddress = pImageSectionHeader[uIndex].VirtualAddress; |
481 | SizeOfSection = __Max(pImageSectionHeader[uIndex].SizeOfRawData, |
482 | pImageSectionHeader[uIndex].Misc.VirtualSize); |
483 |
484 | PointerToRawData = pImageSectionHeader[uIndex].PointerToRawData; |
485 | FileOffset.QuadPart = PointerToRawData; |
486 |
487 | Status = ZwReadFile(hFile, NULL, NULL, NULL, &IoStatusBlock, ( PVOID )(( ULONG )lpVirtualPointer + SecVirtualAddress), |
488 | SizeOfSection, &FileOffset, NULL); |
489 |
490 | if (!NT_SUCCESS(Status)) |
491 | { |
492 | DbgPrint( "ZwReadFile ImageSectionHeader Error --- %#X" , Status); |
493 | ExFreePool(pImageSectionHeader); |
494 | ExFreePool(lpVirtualPointer); |
495 | ZwClose(hFile); |
496 | return Status; |
497 | } |
498 |
499 | } |
500 |
501 | //基址重定位 |
502 | RelocModule(lpVirtualPointer, pOrigImage); |
503 | SetNewSSDT(lpVirtualPointer, pOrigImage, &g_pNewSeviceTable); |
504 | //DbgPrint("RelocModule ok!"); |
505 |
506 | //释放内存 |
507 | ExFreePool(pImageSectionHeader); |
508 | *lpVirtualAddress = lpVirtualPointer; |
509 | DbgPrint( "文件内存复制成功" ); |
510 |
511 | ZwClose(hFile); |
512 | |
513 | return STATUS_SUCCESS; |
514 | } |
515 |
516 |
517 |
518 | PLDR_DATA_TABLE_ENTRY SearchDriver(PDRIVER_OBJECT pDriverObject, wchar_t *strDriverName) |
519 | { |
520 | |
521 | ULONG Base = 0; //模块基地址 |
522 | LDR_DATA_TABLE_ENTRY* SectionBase = 0; |
523 | LIST_ENTRY* Entry = 0; |
524 | LIST_ENTRY InLoadOrderLinks = { 0 }; |
525 | UNICODE_STRING usModuleName; |
526 |
527 | RtlInitUnicodeString(&usModuleName, strDriverName); |
528 | Entry = ((LIST_ENTRY*)pDriverObject->DriverSection)->Flink; |
529 |
530 |
531 | do { |
532 | SectionBase = CONTAINING_RECORD(Entry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks); //得到这个Entry所属的Section的地址,此方法经过验证可行 |
533 | if (SectionBase->EntryPoint && |
534 | SectionBase->BaseDllName.Buffer && |
535 | SectionBase->FullDllName.Buffer && |
536 | SectionBase->LoadCount |
537 | ) |
538 | { |
539 | //KdPrint(("%wZ", &SectionBase->BaseDllName)); |
540 | //DbgPrint("模块名称:%wZ,地址:%x\n", &(SectionBase->FullDllName), SectionBase->DllBase); |
541 | if (0 == RtlCompareUnicodeString(&SectionBase->BaseDllName, &usModuleName, FALSE)) |
542 | { |
543 | KdPrint(( "----%wZ-----" , &SectionBase->BaseDllName)); |
544 | return SectionBase; |
545 | } |
546 | //DbgPrint("方法一遍历模块名称:%wZ,地址:%x\n", &(SectionBase->FullDllName), SectionBase->DllBase); |
547 | } |
548 | Entry = Entry->Flink; |
549 | } while (Entry != ((LIST_ENTRY*)pDriverObject->DriverSection)->Flink); //直到遍历回来 |
550 |
551 | return 0; |
552 | } |
553 |
554 |
555 |
556 | VOID DriverUnload(IN PDRIVER_OBJECT pDriverObject) |
557 | { |
558 | DbgPrint( "DriverUnload" ); |
559 |
560 | if (g_lpVirtualPointer) |
561 | { |
562 | ExFreePool(g_lpVirtualPointer); |
563 | UnHookKiFastCallEntry(); |
564 | } |
565 | } |
566 |
567 |
568 |
569 | NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObject, IN PUNICODE_STRING RegistryPath) |
570 | { |
571 | //C:\WINDOWS\system32\ntkrnlpa.exe |
572 | //ReadFileToMemory(L"\\??\\C:\\WINDOWS\\system32\\ntkrnlpa.exe", &g_lpVitutalPointer, (PVOID)0x804D8000); |
573 | //Method1(pDriverObject); |
574 | PLDR_DATA_TABLE_ENTRY pLdrDataTableEntry; |
575 | pLdrDataTableEntry = SearchDriver(pDriverObject, L "ntoskrnl.exe" ); |
576 | //g_lpVitutalPointer |
577 | if (pLdrDataTableEntry) |
578 | { |
579 | ReadFileToMemory(L "\\??\\C:\\Windows\\System32\\ntkrnlpa.exe" , &g_lpVirtualPointer, pLdrDataTableEntry->DllBase); |
580 | KdPrint(( "g_lpVirtualPointer:%X" , g_lpVirtualPointer)); |
581 | g_NewKernelInc = ( ULONG )g_lpVirtualPointer - ( ULONG )pLdrDataTableEntry->DllBase; |
582 | SearchKiFastCallEntry(); |
583 | } |
584 |
585 |
586 | pDriverObject->DriverUnload = DriverUnload; |
587 | DbgPrint( "DriverEntry" ); |
588 | |
589 | return STATUS_SUCCESS; |
590 | } |
0则评论给“[驱动开发] windows内核重载(xp3) 完整代码”