Windows驱动开发学习记录-遍历内核已加载模块之一(使用DriverSection)

  • 附另两种方法链接:

《Windows驱动开发学习记录-遍历内核已加载模块之二(使用ZwQuerySystemInformation)》

《Windows驱动开发学习记录-遍历内核已加载模块之三(使用 AuxKlib)》

 

 

1.关键结构体

   _LDR_DATA_TABLE_ENTRY为所需要的结构体,具体说明和如何获取该结构体数据见《Windows驱动开发学习记录-驱动中获取当前驱动文件路径》

        现在需要的是该结构体InLoadOrderLinks,这个链表为所有已加载的内核模块的_LDR_DATA_TABLE_ENTRY结构的指针,通过遍历这个链表就可以获取所有已加载的内核模块数据,再取该结构的FullDllName或者BaseDllName即为加载的内核模块的名称和全路径。

 

2.结构体_LDR_DATA_TABLE_ENTRY重要成员

0: kd> dt _LDR_DATA_TABLE_ENTRY
nt!_LDR_DATA_TABLE_ENTRY
   +0x000 InLoadOrderLinks : _LIST_ENTRY
   +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
    ......        

  具体详细结构见《Windows驱动开发学习记录-驱动中获取当前驱动文件路径 》

 

3.实现

  代码如下,实测 XP 32位、Win7 64位以及Win10 64位都能Pass。

.h文件

 1 //头文件
 2  
 3 #if DBG
 4 #define KDPRINT(projectName, format, ...) DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL,    projectName "::【" __FUNCTION__  "】" ##format,  ##__VA_ARGS__ ) 
 5 #else
 6 #define KDPRINT(format, ...)
 7 #endif
 8 
 9 typedef enum
10 {
11         MmTagTypeDS     = 'SD'             //PrintAllLoadedMoudleByDriverSection
12 }MmTagType;
13  
14 typedef struct _LDR_DATA_TABLE_ENTRY {
15         LIST_ENTRY InLoadOrderLinks;
16         LIST_ENTRY InMemoryOrderLinks;
17         LIST_ENTRY InInitializationOrderLinks;
18         PVOID DllBase;
19         PVOID EntryPoint;
20         ULONG SizeOfImage;
21         UNICODE_STRING FullDllName;
22         UNICODE_STRING BaseDllName;
23         union {
24                 ULONG FlagGroup;
25                 ULONG Flags;
26         };
27 }LDR_DATA_TABLE_ENTRY, * PLDR_DATA_TABLE_ENTRY;

 

.cpp文件

 1 //.cpp
 2 NTSTATUS PrintAllLoadedMoudleByDriverSection(PDRIVER_OBJECT pDriverOjbect)
 3 {
 4         NTSTATUS ntStatus = STATUS_SUCCESS;
 5         if ((pDriverOjbect) && (pDriverOjbect->DriverSection))
 6         {
 7                 ANSI_STRING asBaseDllName = { 0 };
 8                 ANSI_STRING asFullDllName = { 0 };
 9                 PCHAR pBaseDllNameBufer = NULL;
10                 PCHAR pFullDllNameBufer = NULL;
11                 do
12                 {
13                         pBaseDllNameBufer = (PCHAR)ExAllocatePoolWithTag(PagedPool, USHORT_MAX, MmTagTypeDS);
14                         if (pBaseDllNameBufer == NULL)
15                         {
16                                 KDPRINT("【PrintLoadedModule】", "pBaseDllNameBufer Allocate Memory Failed!\r\n");
17                                 ntStatus = STATUS_INSUFFICIENT_RESOURCES;
18                                 break;
19                         }
20                         RtlZeroMemory(pBaseDllNameBufer, USHORT_MAX);
21                         pFullDllNameBufer = (PCHAR)ExAllocatePoolWithTag(PagedPool, USHORT_MAX, MmTagTypeDS);
22                         if (pFullDllNameBufer == NULL)
23                         {
24                                 KDPRINT("【PrintLoadedModule】", "pFullDllNameBufer Allocate Memory Failed!\r\n");
25                                 ntStatus = STATUS_INSUFFICIENT_RESOURCES;
26                                 break;
27                         }
28                         RtlZeroMemory(pFullDllNameBufer, USHORT_MAX);
29                         RtlInitEmptyAnsiString(&asBaseDllName, pBaseDllNameBufer, USHORT_MAX);
30                         RtlInitEmptyAnsiString(&asFullDllName, pFullDllNameBufer, USHORT_MAX);
31                         PLDR_DATA_TABLE_ENTRY pldte = (PLDR_DATA_TABLE_ENTRY)pDriverOjbect->DriverSection;
32                         if (pldte != NULL)
33                         {
34                                 const PLIST_ENTRY pListHeaderInLoadOrder = pldte->InLoadOrderLinks.Flink;
35                                 if (pListHeaderInLoadOrder != NULL)
36                                 {
37                                         ULONG ulCount = 0;
38                                         PLIST_ENTRY pListTemp = pListHeaderInLoadOrder;
39                                         do
40                                         {
41                                                 PLDR_DATA_TABLE_ENTRY pldteTemp = (PLDR_DATA_TABLE_ENTRY)CONTAINING_RECORD(
42                                                         pListTemp,
43                                                         LDR_DATA_TABLE_ENTRY64,
44                                                         InLoadOrderLinks);
45                                                 if ((pldteTemp != NULL) &&
46                                                      (pldteTemp->BaseDllName.Buffer != NULL) &&
47                                                      (pldteTemp->FullDllName.Buffer != NULL))
48                                                 {
49                                                         //1.直接通过DbgPrintEx的 %wZ参数打印 BaseDllName和FullDllName时在XP系统下当时文件路径
50                                                         // 中有中文的时候会截断,故先转化为ANSI类型再打印,如不需要打印则可将相关ANSI类型的定义
51                                                         // 初始化以及转换去掉
52                                                         //2.节点遍历过程中有一个空节点,其中字符串的Buffer为空,通过BaseDllName.Buffer以及
53                                                         //FullDllName.Buffer为空来跳过
54                                                         //KDPRINT("【PrintLoadedModule】","Name:%-30wZ Path:%wZ\r\n",
55                                                         //                                                              &pldteTemp->BaseDllName, &pldteTemp->FullDllName);
56                                                         RtlUnicodeStringToAnsiString(&asBaseDllName, &pldteTemp->BaseDllName, false);
57                                                         RtlUnicodeStringToAnsiString(&asFullDllName, &pldteTemp->FullDllName, false);
58                                                         KDPRINT("【PrintLoadedModule】", "Name:%-30Z Path:%-130Z Base:0x%p\r\n",
59                                                                 &asBaseDllName, &asFullDllName, pldteTemp->DllBase);
60 
61                                                         ulCount++;
62                                                 }
63                                                 pListTemp = pListTemp->Flink;
64 
65                                         } while (pListTemp != pListHeaderInLoadOrder);
66 
67                                         KDPRINT("【PrintLoadedModule】", "共计%d个内核模块!\r\n", ulCount);
68                                 }
69                         }
70                 } while (false);
71                 if (pBaseDllNameBufer)
72                 {
73                         ExFreePoolWithTag(pBaseDllNameBufer, MmTagTypeDS);
74                         pBaseDllNameBufer = NULL;
75                 }
76                 if (pFullDllNameBufer)
77                 {
78                         ExFreePoolWithTag(pFullDllNameBufer, MmTagTypeDS);
79                         pFullDllNameBufer = NULL;
80                 }
81         }
82         return ntStatus;
83 }
84 
85 
86 EXTERN_C NTSTATUS  DriverEntry(PDRIVER_OBJECT pDriverObject,
87         PUNICODE_STRING pRegistryPath)
88 {
89         PrintAllLoadedMoudleByDriverSection(pDriverObject);
90         return STATUS_SUCCESS;
91 }

 

 

4.运行效果

  xp 32位:

 Win10 64位:

posted @ 2021-11-25 13:36  禁锢在时空之中的灵魂  阅读(269)  评论(0编辑  收藏  举报