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 {
  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;
	}
}

效果图:
在这里插入图片描述

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 很高兴能够回答你的问题。PythonOS模块是一个Python语言开发的操作系统,可以帮助用户快速构建自定义的操作系统,其功能包括:文件管理、网络支持、硬件驱动程序、多任务处理以及系统管理等。它还支持多种应用程序,可以满足不同用户的需求。 ### 回答2: Python的os模块是一个用于与操作系统进行交互的库。这个模块提供了多个函数,可以让我们对文件和目录进行操作。 首先,os模块提供了一些基本的文件和目录操作函数,比如创建和删除目录,读和写入文件等。我们可以使用os.mkdir(path)函数来创建一个新的目录,使用os.rmdir(path)函数来删除一个空目录,使用os.remove(path)函数来删除一个文件。 此外,os模块还提供了一些文件和目录的查询和修改函数。我们可以使用os.path.exists(path)函数来判断一个文件或者目录是否存在,使用os.path.isfile(path)函数来判断一个路径是否为文件,使用os.path.isdir(path)函数来判断一个路径是否为目录。另外,我们还可以使用os.rename(src, dst)函数来重命名一个文件或者目录,使用os.getcwd()函数来获当前工作目录。 os模块也提供了一些对文件和目录进行遍历的函数。比如,我们可以使用os.listdir(path)函数来列出一个目录中的所有文件和子目录。同时,os模块还提供了一些高级的文件和目录操作函数,包括文件的复制和移动等。 总之,os模块是Python中一个非常有用的模块,它为我们提供了许多处理文件和目录的函数,方便我们进行文件操作和系统管理。无论是创建、删除、修改,还是查询和遍历文件和目录,os模块都提供了一系列的函数来满足我们的需求。 ### 回答3: Python的os模块是用于处理操作系统相关功能的模块。它提供了一些方法,可以在Python程序中执行与操作系统交互的操作,比如文件和目录的管理,执行命令等。 其中,os模块的一些常用方法如下: 1. os.name方法:用于获当前操作系统的名称,可以返回"posix"表示Linux,Unix或Mac OS X;返回"nt"表示Windows。 2. os.getcwd方法:用于获当前工作目录的路径。 3. os.chdir方法:用于改变当前工作目录的路径。 4. os.listdir方法:用于获指定目录下的所有文件和子目录的列表。 5. os.mkdir方法:用于创建目录。 6. os.rmdir方法:用于删除目录。 7. os.remove方法:用于删除文件。 8. os.path模块:提供了一些用于处理文件路径的方法,如os.path.join用于拼接路径,os.path.abspath用于获绝对路径等。 9. os.system方法:用于执行操作系统的命令。 这些只是os模块的一部分方法,还有很多其他的方法可以用于文件和目录的操作。总之,os模块提供了丰富的功能,方便我们在Python程序中处理与操作系统相关的任务。无论是文件管理还是执行命令,os模块都可以提供便捷的操作方式,使得编写Python程序更加灵活和高效。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值