x64驱动 遍历驱动模块

知是行的主意,行是知的功夫。这篇文章主要讲述x64驱动 遍历驱动模块相关的知识,希望能为你提供帮助。
_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
CSHORTType; // 类型
CSHORTSize; // 大小
PDEVICE_OBJECTDeviceObject; // 设备对象指针
ULONGFlags; // 标志
PVOIDDriverStart; // 驱动起始地址
ULONGDriverSize; // 驱动大小
PVOIDDriverSection; // 驱动节< ---------- 【我们用到的成员,它指向 _LDR_DATA_TABLE_ENTRY 结构】
PDRIVER_EXTENSIONDriverExtension; // 驱动程序扩展的指针
UNICODE_STRINGDriverName; // 驱动名
PUNICODE_STRINGHardwareDatabase; // 指向注册表 \\Registry\\Machine\\Hardware 的指针
PFAST_IO_DISPATCHFastIoDispatch; // 指向驱动快速 I/O 入口的指针
PDRIVER_INITIALIZE DriverInit; // 驱动程序入口点
PDRIVER_STARTIODriverStartIo; // 驱动程序启动函数入口点
PDRIVER_UNLOADDriverUnload; // 驱动程序卸载函数入口点
PDRIVER_DISPATCHMajorFunction[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_STRINGRegistryPath)

// 定义返回值
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;


效果图:




【x64驱动 遍历驱动模块】


    推荐阅读