_LDR_DATA_TABLE_ENTRY(未导出)
以下是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 // 签名等级
_DRIVER_OBJECT
typedef struct _DRIVER_OBJECT {
CSHORT Type; // 类型
CSHORT Size; // 大小
PDEVICE_OBJECT DeviceObject; // 设备对象指针
ULONG Flags; // 标志
PVOID DriverStart; // 驱动起始地址
ULONG DriverSize; // 驱动大小
PVOID DriverSection; // 驱动节 <---------- 【我们用到的成员,它指向 _LDR_DATA_TABLE_ENTRY 结构】
PDRIVER_EXTENSION DriverExtension; // 驱动程序扩展的指针
UNICODE_STRING DriverName; // 驱动名
PUNICODE_STRING HardwareDatabase; // 指向注册表 \Registry\Machine\Hardware 的指针
PFAST_IO_DISPATCH FastIoDispatch; // 指向驱动快速 I/O 入口的指针
PDRIVER_INITIALIZE DriverInit; // 驱动程序入口点
PDRIVER_STARTIO DriverStartIo; // 驱动程序启动函数入口点
PDRIVER_UNLOAD DriverUnload; // 驱动程序卸载函数入口点
PDRIVER_DISPATCH MajorFunction[IRP_MJ_MAXIMUM_FUNCTION + 1]; // IRP 函数入口点
} DRIVER_OBJECT, *PDRIVER_OBJECT;
代码:
// 定义 _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;
}
}
效果图: