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

  • 附另两种方法链接:

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

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

1.关键结构体

        _LDR_DATA_TABLE_ENTRY为所需要的结构体,具体说明和如何获取该结构体数据见<>。

        现在需要的是该结构体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
    ......        

         具体详细结构见<>

3.实现

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

//头文件

typedef enum
{
        MmTagTypeDS     = 'SD'             //PrintAllLoadedMoudleByDriverSection
}MmTagType;

typedef struct _LDR_DATA_TABLE_ENTRY {
        LIST_ENTRY InLoadOrderLinks;
        LIST_ENTRY InMemoryOrderLinks;
        LIST_ENTRY InInitializationOrderLinks;
        PVOID DllBase;
        PVOID EntryPoint;
        ULONG SizeOfImage;
        UNICODE_STRING FullDllName;
        UNICODE_STRING BaseDllName;
        union {
                ULONG FlagGroup;
                ULONG Flags;
        };
}LDR_DATA_TABLE_ENTRY, * PLDR_DATA_TABLE_ENTRY;
#include 

NTSTATUS PrintAllLoadedMoudleByDriverSection(PDRIVER_OBJECT pDriverOjbect)
{
        NTSTATUS ntStatus = STATUS_SUCCESS;
        if ((pDriverOjbect) && (pDriverOjbect->DriverSection))
        {
                ANSI_STRING asBaseDllName = { 0 };
                ANSI_STRING asFullDllName = { 0 };
                PCHAR pBaseDllNameBufer = NULL;
                PCHAR pFullDllNameBufer = NULL;
                do
                {
                        pBaseDllNameBufer = (PCHAR)ExAllocatePoolWithTag (PagedPool, USHORT_MAX, MmTagTypeDS);
                        if (pBaseDllNameBufer == NULL)
                        {
                                KDPRINT("【PrintLoadedModule】::【PrintAllLoadedMoudleByDriverSection】pBaseDllNameBufer Allocate Memory Failed!\r\n");
                                ntStatus = STATUS_INSUFFICIENT_RESOURCES;
                                break;
                        }
                        RtlZeroMemory(pBaseDllNameBufer, USHORT_MAX);
                        pFullDllNameBufer = (PCHAR)ExAllocatePoolWithTag(PagedPool, USHORT_MAX, MmTagTypeDS);
                        if (pFullDllNameBufer == NULL)
                        {
                                KDPRINT("【PrintLoadedModule】::【PrintAllLoadedMoudleByDriverSection】pFullDllNameBufer Allocate Memory Failed!\r\n");
                                ntStatus = STATUS_INSUFFICIENT_RESOURCES;
                                break;
                        }
                        RtlZeroMemory(pFullDllNameBufer, USHORT_MAX);
                        RtlInitEmptyAnsiString(&asBaseDllName, pBaseDllNameBufer, USHORT_MAX);
                        RtlInitEmptyAnsiString(&asFullDllName, pFullDllNameBufer, USHORT_MAX);
                        PLDR_DATA_TABLE_ENTRY pldte = (PLDR_DATA_TABLE_ENTRY)pDriverOjbect->DriverSection;
                        if (pldte != NULL)
                        {
                                const PLIST_ENTRY pListHeaderInLoadOrder = pldte->InLoadOrderLinks.Flink;
                                if (pListHeaderInLoadOrder != NULL)
                                {
                                        ULONG ulCount = 0;
                                        PLIST_ENTRY pListTemp = pListHeaderInLoadOrder;
                                        do 
                                        {
                                                PLDR_DATA_TABLE_ENTRY pldteTemp = (PLDR_DATA_TABLE_ENTRY)CONTAINING_RECORD(
                                                        pListTemp,
                                                        LDR_DATA_TABLE_ENTRY64,
                                                        InLoadOrderLinks);
                                                if ((pldteTemp != NULL) && 
                                                     (pldteTemp->BaseDllName.Buffer != NULL) &&
                                                     (pldteTemp->FullDllName.Buffer != NULL))
                                                {
                                                        //1.直接通过DbgPrintEx的 %wZ参数打印 BaseDllName和FullDllName时在XP系统下当时文件路径
                                                        // 中有中文的时候会截断,故先转化为ANSI类型再打印,如不需要打印则可将相关ANSI类型的定义
                                                        // 初始化以及转换去掉
                                                        //2.节点遍历过程中有一个空节点,其中字符串的Buffer为空,通过BaseDllName.Buffer以及
                                                        //FullDllName.Buffer为空来跳过
                                                        //KDPRINT("【PrintLoadedModule】::【PrintAllLoadedMoudleByDriverSection】Name:%-30wZ Path:%wZ\r\n",
                                                        //                                                              &pldteTemp->BaseDllName, &pldteTemp->FullDllName);
                                                        RtlUnicodeStringToAnsiString(&asBaseDllName, &pldteTemp->BaseDllName, false);
                                                        RtlUnicodeStringToAnsiString(&asFullDllName, &pldteTemp->FullDllName, false);
                                                        KDPRINT("【PrintLoadedModule】::【PrintAllLoadedMoudleByDriverSection】Name:%-30Z Path:%-130Z Base:0x%p\r\n",
                                                                &asBaseDllName, &asFullDllName, pldteTemp->DllBase);
                                                                
                                                        ulCount++;                                        
                                                }
                                                pListTemp = pListTemp->Flink;
                                                
                                        } while (pListTemp != pListHeaderInLoadOrder);

                                        KDPRINT("【PrintLoadedModule】::【PrintAllLoadedMoudleByDriverSection】共计%d个内核模块!\r\n", ulCount);
                                }      
                        }
                } while (false);
                if (pBaseDllNameBufer)
                {
                        ExFreePoolWithTag(pBaseDllNameBufer, MmTagTypeDS);
                        pBaseDllNameBufer = NULL;
                }
                if (pFullDllNameBufer)
                {
                        ExFreePoolWithTag(pFullDllNameBufer, MmTagTypeDS);
                        pFullDllNameBufer = NULL;
                }
        }
        return ntStatus;
}


EXTERN_C NTSTATUS  DriverEntry(PDRIVER_OBJECT pDriverObject,
        PUNICODE_STRING pRegistryPath)
{
        PrintAllLoadedMoudleByDriverSection(pDriverObject);
        return STATUS_SUCCESS;
}

 运行结果:

        XP 32位:

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

        Win10 64位:

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

你可能感兴趣的:(Windows内核,windows,c++,链表)