以下是win10 1803(x64) 上的 _LDR_DATA_TABLE_ENTRY:
lkd> dt _LDR_DATA_TABLE_ENTRY nt!_LDR_DATA_TABLE_ENTRY +0x000 InLoadOrderLinks : _LIST_ENTRY // 指向下一个 _LDR_DATA_TABLE_ENTRY 的 InLoadOrderLinks 成员 +0x010 InMemoryOrderLinks : _LIST_ENTRY // 不要使用(蓝屏) +0x020 InInitializationOrderLinks : _LIST_ENTRY // 不要使用(蓝屏) +0x030 DllBase : Ptr64 Void // 驱动模块基地址 +0x038 EntryPoint : Ptr64 Void // 驱动入口点 +0x040 SizeOfImage : Uint4B // 驱动模块大小 +0x048 FullDllName : _UNICODE_STRING // 驱动模块全路径 +0x058 BaseDllName : _UNICODE_STRING // 驱动模块名 +0x068 FlagGroup : [4] UChar // 标志组 +0x068 Flags : Uint4B // 标志 +0x068 PackagedBinary : Pos 0, 1 Bit +0x068 MarkedForRemoval : Pos 1, 1 Bit +0x068 ImageDll : Pos 2, 1 Bit +0x068 LoadNotificationsSent : Pos 3, 1 Bit +0x068 TelemetryEntryProcessed : Pos 4, 1 Bit +0x068 ProcessStaticImport : Pos 5, 1 Bit +0x068 InLegacyLists : Pos 6, 1 Bit +0x068 InIndexes : Pos 7, 1 Bit +0x068 ShimDll : Pos 8, 1 Bit +0x068 InExceptionTable : Pos 9, 1 Bit +0x068 ReservedFlags1 : Pos 10, 2 Bits +0x068 LoadInProgress : Pos 12, 1 Bit +0x068 LoadConfigProcessed : Pos 13, 1 Bit +0x068 EntryProcessed : Pos 14, 1 Bit +0x068 ProtectDelayLoad : Pos 15, 1 Bit +0x068 ReservedFlags3 : Pos 16, 2 Bits +0x068 DontCallForThreads : Pos 18, 1 Bit +0x068 ProcessAttachCalled : Pos 19, 1 Bit +0x068 ProcessAttachFailed : Pos 20, 1 Bit +0x068 CorDeferredValidate : Pos 21, 1 Bit +0x068 CorImage : Pos 22, 1 Bit +0x068 DontRelocate : Pos 23, 1 Bit +0x068 CorILOnly : Pos 24, 1 Bit +0x068 ChpeImage : Pos 25, 1 Bit +0x068 ReservedFlags5 : Pos 26, 2 Bits +0x068 Redirected : Pos 28, 1 Bit +0x068 ReservedFlags6 : Pos 29, 2 Bits +0x068 CompatDatabaseProcessed : Pos 31, 1 Bit +0x06c ObsoleteLoadCount : Uint2B // 负载计数 +0x06e TlsIndex : Uint2B // TLS 索引 +0x070 HashLinks : _LIST_ENTRY // Hash 链表 +0x080 TimeDateStamp : Uint4B // 日期标志 +0x088 EntryPointActivationContext : Ptr64 _ACTIVATION_CONTEXT // 入口点激活上下文 +0x090 Lock : Ptr64 Void // 锁 +0x098 DdagNode : Ptr64 _LDR_DDAG_NODE // DDAG 节点 +0x0a0 NodeModuleLink : _LIST_ENTRY // 模块节点链表 +0x0b0 LoadContext : Ptr64 _LDRP_LOAD_CONTEXT // 加载上下文 +0x0b8 ParentDllBase : Ptr64 Void // 父模块基地址 +0x0c0 SwitchBackContext : Ptr64 Void // 回转上下文 +0x0c8 BaseAddressIndexNode : _RTL_BALANCED_NODE // 基地址索引节点 +0x0e0 MappingInfoIndexNode : _RTL_BALANCED_NODE // 映射信息索引节点 +0x0f8 OriginalBase : Uint8B // 原始基地址 +0x100 LoadTime : _LARGE_INTEGER // 加载时间 +0x108 BaseNameHashValue : Uint4B // 返回路径中的文件名哈希值 +0x10c LoadReason : _LDR_DLL_LOAD_REASON // 加载原因 +0x110 ImplicitPathOptions : Uint4B // 隐式路径设置 +0x114 ReferenceCount : Uint4B // 参考数目 +0x118 DependentLoadFlags : Uint4B // 附属加载标志 +0x11c SigningLevel : UChar // 签名等级代码:
// 定义 _LDR_DATA_TABLE_ENTRY 结构(因为我只用到了结构的一部分所以没有把 windbg 所有的成员都拷贝过来) typedef struct _LDR_DATA_TABLE_ENTRY { LIST_ENTRY InLoadOrderLinks; // 指向下一个 _LDR_DATA_TABLE_ENTRY 的 InLoadOrderLinks LIST_ENTRY InMemoryOrderLinks; LIST_ENTRY InInitializationOrderLinks; PVOID DllBase; // 模块基地址 PVOID EntryPoint; // 入口点 ULONG SizeOfImage; // 驱动大小 UNICODE_STRING FullDllName; // 模块全路径 UNICODE_STRING BaseDllName; // 模块名 }LDR_DATA_TABLE_ENTRY, * PLDR_DATA_TABLE_ENTRY; extern "C" NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath){ // 定义返回值 NTSTATUS status; // 输出日志 DbgPrint("[LYSM] DriverEntry start.\n"); // 指定驱动卸载函数 DriverObject->DriverUnload = (PDRIVER_UNLOAD)DriverUnload; // 初始化 PLDR_DATA_TABLE_ENTRY 实例 PLDR_DATA_TABLE_ENTRY pLdr = (PLDR_DATA_TABLE_ENTRY)DriverObject->DriverSection; // 定义 InLoadOrderLinks 双向链表头 PLIST_ENTRY pListEntry = pLdr->InLoadOrderLinks.Flink; // 定义 InLoadOrderLinks 当前节点 PLIST_ENTRY pCurrentListEntry = pListEntry->Flink; // 遍历双向链表 PLDR_DATA_TABLE_ENTRY pCurrentModule = NULL; while (pCurrentListEntry != pListEntry){ // 根据成员反推基地址 pCurrentModule = CONTAINING_RECORD(pCurrentListEntry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks); if (!MmIsAddressValid(pCurrentModule)) { DbgPrint("[LYSM] pCurrentModule 不可读 \n"); goto while_end; } // 打印 DbgPrint("[LYSM] DllBase:%p \n", pCurrentModule->DllBase); DbgPrint("[LYSM] EntryPoint:%p \n", pCurrentModule->EntryPoint); DbgPrint("[LYSM] SizeOfImage:%p \n", pCurrentModule->SizeOfImage); DbgPrint("[LYSM] FullDllName:%wZ \n", pCurrentModule->FullDllName); DbgPrint("[LYSM] BaseDllName:%wZ \n", pCurrentModule->BaseDllName); while_end: pCurrentListEntry = pCurrentListEntry->Flink; } }效果图: