Windows驱动开发学习记录-遍历内核已加载模块之三(使用 AuxKlib)
-
附另两种方法链接
1.主要区别
上面两个链接使用的方法中的函数或者结构体都为未文档化的,所以存在不同系统环境下结构体或者其它定义不同的情况,可能需要针对性调试系统才能获取。而当前文档介绍的方法为文档化的。
2.原型
NTSTATUS AuxKlibQueryModuleInformation(
PULONG BufferSize,
ULONG ElementSize,
PVOID QueryInfo
);
参数:
- BufferSize 【In/Out】 一个指向接收数据缓冲区大小的指针,大小为字节。如果QueryInfo为空,该值为驱动必须分配的接收获取的信息的大小的字节数。如果QueryInfo不为空,则为给定的缓冲区大小。
- ElementSize【In】 QueryInfo指针指向数组中每个元素的字节大小,可设定的值为sizeof(AUX_MODULE_BASIC_INFO)或sizeof(AUX_MODULE_EXTENDED_INFO)。
- QueryInfo【Out/Optional】 指向结构体AUX_MODULE_BASIC_INFO 或者AUX_MODULE_EXTENDED_INFO 数组的指针,该数组用来接受已加载模块的信息。如果指针为空,AuxKlibQueryModuleInformation 将需要的缓冲区大小写入BufferSize指针
返回值:
操作成功返回STATUS_SUCCESS ;
如果QueryInfo 不为空,且驱动提供的缓冲区大小不够则返回STATUS_BUFFER_TOO_SMALL ;
可能还会返回其它NTSTATUS值。
备注:
要获取系统加载模块信息,驱动必须做以下操作:
1、调用AuxKlibQueryModuleInformation且QueryInfo传空,返回后BufferSize为需要分配缓冲区字节大小数。
2、调用内存申请例程,例如 ExAllocatePoolWithTag,为该数组分配缓冲区。
3、再次调用AuxKlibQueryModuleInformation,QueryInfo为申请的缓冲区地址指针。AuxKlibQueryModuleInformation返回后,缓冲区包含加载模块的数组。
在使用AuxKlibQueryModuleInformation之前必须调用AuxKlibInitialize。
要求:
头文件aux_klib.h (include Aux_klib.h)
包含库 Aux_Klib.lib
3.结构体
typedef struct _AUX_MODULE_BASIC_INFO {
PVOID ImageBase;
} AUX_MODULE_BASIC_INFO, *PAUX_MODULE_BASIC_INFO;
typedef struct _AUX_MODULE_EXTENDED_INFO {
AUX_MODULE_BASIC_INFO BasicInfo;
ULONG ImageSize;
USHORT FileNameOffset;
UCHAR FullPathName[AUX_KLIB_MODULE_PATH_LEN];
} AUX_MODULE_EXTENDED_INFO, *PAUX_MODULE_EXTENDED_INFO;
4.代码实现
头文件:
#if DBG
#define KDPRINT(projectName, format, ...) DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, projectName "::【" __FUNCTION__ "】" ##format, ##__VA_ARGS__ )
#else
#define KDPRINT(format, ...)
#endif
typedef enum
{
MmTagTypeAux = 'XUA',
}MmTagType;
CPP文件:
1 NTSTATUS PrintAllLoadedMoudleByAux() 2 { 3 NTSTATUS ntStatus = STATUS_UNSUCCESSFUL; 4 PAUX_MODULE_EXTENDED_INFO pModules = NULL; 5 ULONG ulMoudleSize = 0; 6 ULONG ulNumberOfModules = 0; 7 do 8 { 9 ntStatus = AuxKlibInitialize(); 10 if (!NT_SUCCESS(ntStatus)) 11 { 12 KDPRINT("【PrintLoadedModule】", "AuxKlibInitialize Failed!\r\n"); 13 break; 14 } 15 ntStatus = AuxKlibQueryModuleInformation( 16 &ulMoudleSize, 17 sizeof(AUX_MODULE_EXTENDED_INFO), 18 NULL); 19 if (STATUS_BUFFER_TOO_SMALL == ntStatus || ulMoudleSize != 0) 20 { 21 ulNumberOfModules = ulMoudleSize / sizeof(AUX_MODULE_EXTENDED_INFO); 22 23 pModules = (PAUX_MODULE_EXTENDED_INFO)ExAllocatePoolWithTag(PagedPool, ulMoudleSize, MmTagTypeAux); 24 if (pModules == NULL) 25 { 26 KDPRINT("【PrintLoadedModule】", "ExAllocatePoolWithTag Failed!\r\n"); 27 ntStatus = STATUS_INSUFFICIENT_RESOURCES; 28 break; 29 } 30 RtlZeroMemory(pModules, ulMoudleSize); 31 ntStatus = AuxKlibQueryModuleInformation( 32 &ulMoudleSize, 33 sizeof(AUX_MODULE_EXTENDED_INFO), 34 pModules); 35 if (!NT_SUCCESS(ntStatus)) 36 { 37 KDPRINT("【PrintLoadedModule】", "AuxKlibQueryModuleInformation 2 Failed!\r\n"); 38 break; 39 } 40 for (ULONG i = 0; i < ulNumberOfModules; i++) 41 { 42 KDPRINT("【PrintLoadedModule】", "Path:%-50s BaseAddress:0x%p\r\n", 43 pModules[i].FullPathName, pModules[i].BasicInfo.ImageBase); 44 } 45 KDPRINT("【PrintLoadedModule】", "共计%d个内核模块!\r\n", ulNumberOfModules); 46 } 47 48 } while (false); 49 if (pModules) 50 { 51 ExFreePoolWithTag(pModules, MmTagTypeAux); 52 } 53 return ntStatus; 54 }
5.运行结果
- xp 32位:
- win10 x64