就是一个调用api的操作,具体可以查微软和百度具体含义
案例代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
| #include <ntddk.h> #include <ntimage.h>
PUCHAR PsGetProcessImageFileName(PEPROCESS pEProcess);
PVOID GetDriverEntryByImageBase(PVOID ImageBase) { PIMAGE_DOS_HEADER pDOSHeader; PIMAGE_NT_HEADERS64 pNTHeader; PVOID pEntryPoint; pDOSHeader = (PIMAGE_DOS_HEADER)ImageBase; pNTHeader = (PIMAGE_NT_HEADERS64)((ULONG64)ImageBase + pDOSHeader->e_lfanew); pEntryPoint = (PVOID)((ULONG64)ImageBase + pNTHeader->OptionalHeader.AddressOfEntryPoint); return pEntryPoint; }
UCHAR* GetCurrentProcessName() { PEPROCESS pEProcess = PsGetCurrentProcess(); if (NULL != pEProcess) { UCHAR *lpszProcessName = PsGetProcessImageFileName(pEProcess); if (NULL != lpszProcessName) { return lpszProcessName; } } return NULL; }
VOID MyLySharkLoadImageNotifyRoutine(PUNICODE_STRING FullImageName, HANDLE ModuleStyle, PIMAGE_INFO ImageInfo) { PVOID pDrvEntry;
if (FullImageName != NULL && MmIsAddressValid(FullImageName)) { if (ModuleStyle == 0) { UCHAR *load_name = GetCurrentProcessName(); pDrvEntry = GetDriverEntryByImageBase(ImageInfo->ImageBase); DbgPrint("[LyShark SYS加载] 模块名称:%wZ --> 装载基址:%p --> 镜像长度: %d --> 装载主进程: %s \n", FullImageName, pDrvEntry, ImageInfo->ImageSize, load_name); } else { UCHAR *load_name = GetCurrentProcessName(); pDrvEntry = GetDriverEntryByImageBase(ImageInfo->ImageBase); DbgPrint("[LyShark DLL加载] 模块名称:%wZ --> 装载基址:%p --> 镜像长度: %d --> 装载主进程: %s \n", FullImageName, pDrvEntry, ImageInfo->ImageSize, load_name); } } }
VOID UnDriver(PDRIVER_OBJECT driver) { PsRemoveLoadImageNotifyRoutine((PLOAD_IMAGE_NOTIFY_ROUTINE)MyLySharkLoadImageNotifyRoutine); DbgPrint("[LyShark.com] 驱动卸载完成..."); }
NTSTATUS DriverEntry(IN PDRIVER_OBJECT Driver, PUNICODE_STRING RegistryPath) { DbgPrint("hello lyshark.com \n");
PsSetLoadImageNotifyRoutine((PLOAD_IMAGE_NOTIFY_ROUTINE)MyLySharkLoadImageNotifyRoutine); DbgPrint("[LyShark.com] 驱动加载完成..."); Driver->DriverUnload = UnDriver; return STATUS_SUCCESS; }
|

windbg手动致盲
这个数组与前面的进程和线程是一样的,致盲方式也是一样的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| lkd> u nt!PsSetLoadImageNotifyRoutineEx L15 nt!PsSetLoadImageNotifyRoutineEx: fffff800`a4e5c970 48895c2408 mov qword ptr [rsp+8],rbx fffff800`a4e5c975 48896c2410 mov qword ptr [rsp+10h],rbp fffff800`a4e5c97a 4889742418 mov qword ptr [rsp+18h],rsi fffff800`a4e5c97f 57 push rdi fffff800`a4e5c980 4883ec20 sub rsp,20h fffff800`a4e5c984 488be9 mov rbp,rcx fffff800`a4e5c987 48f7c2feffffff test rdx,0FFFFFFFFFFFFFFFEh fffff800`a4e5c98e 7569 jne nt!PsSetLoadImageNotifyRoutineEx+0x89 (fffff800`a4e5c9f9) fffff800`a4e5c990 e81b010000 call nt!ExAllocateCallBack (fffff800`a4e5cab0) fffff800`a4e5c995 33db xor ebx,ebx fffff800`a4e5c997 488bf0 mov rsi,rax fffff800`a4e5c99a 4885c0 test rax,rax fffff800`a4e5c99d 7476 je nt!PsSetLoadImageNotifyRoutineEx+0xa5 (fffff800`a4e5ca15) fffff800`a4e5c99f 8bfb mov edi,ebx fffff800`a4e5c9a1 83ff40 cmp edi,40h fffff800`a4e5c9a4 7365 jae nt!PsSetLoadImageNotifyRoutineEx+0x9b (fffff800`a4e5ca0b) fffff800`a4e5c9a6 8bc7 mov eax,edi fffff800`a4e5c9a8 488d0dd17c4a00 lea rcx,[nt!PspLoadImageNotifyRoutine (fffff800`a5304680)] fffff800`a4e5c9af 4533c0 xor r8d,r8d fffff800`a4e5c9b2 488bd6 mov rdx,rsi fffff800`a4e5c9b5 488d0cc1 lea rcx,[rcx+rax*8]
|
和其他方法一样,我们需要确保字节正确 ,偏移量 0x8d48d68b48c03345 保持 0x04,并且找到两个接近 nt 的函数!用于字节搜索的 PsSetLoadImageNotifyRoutineEx。
1 2 3 4
| lkd> dq fffff800`a4e5c9af L1 fffff800`a4e5c9af 8d48d68b`48c03345 lkd> ? nt!PsSetLoadImageNotifyRoutineEx - nt Evaluate expression: 10865008 = 00000000`00a5c970
|

根据截图,导出了 PsSetLoadImageNotifyRoutineEx 函数,我们可以直接使用它,但 Windows 版本之间并非总是这样。所以我仍然会用 RtlAppendStringToString 作为起始,IoInitializeMiniCompletionPacket 作为结尾。


致盲成功。