-
附另两种方法链接
Windows驱动开发学习记录-遍历内核已加载模块之一(使用DriverSection)
Windows驱动开发学习记录-遍历内核已加载模块之二(使用ZwQuerySystemInformation)
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.代码实现
NTSTATUS PrintAllLoadedMoudleByAux()
{
NTSTATUS ntStatus = STATUS_UNSUCCESSFUL;
PAUX_MODULE_EXTENDED_INFO pModules = NULL;
ULONG ulMoudleSize = 0;
ULONG ulNumberOfModules = 0;
do
{
ntStatus = AuxKlibInitialize();
if (!NT_SUCCESS(ntStatus))
{
KDPRINT("【PrintLoadedModule】::【PrintAllLoadedMoudleByAux】AuxKlibInitialize Failed!\r\n");
break;
}
ntStatus = AuxKlibQueryModuleInformation(
&ulMoudleSize,
sizeof(AUX_MODULE_EXTENDED_INFO),
NULL);
if (STATUS_BUFFER_TOO_SMALL == ntStatus || ulMoudleSize != 0)
{
ulNumberOfModules = ulMoudleSize / sizeof(AUX_MODULE_EXTENDED_INFO);
pModules = (PAUX_MODULE_EXTENDED_INFO)ExAllocatePoolWithTag(PagedPool, ulMoudleSize, MmTagTypeAux);
if (pModules == NULL)
{
KDPRINT("【PrintLoadedModule】::【PrintAllLoadedMoudleByAux】ExAllocatePoolWithTag Failed!\r\n");
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
break;
}
RtlZeroMemory(pModules, ulMoudleSize);
ntStatus = AuxKlibQueryModuleInformation(
&ulMoudleSize,
sizeof(AUX_MODULE_EXTENDED_INFO),
pModules);
if (!NT_SUCCESS(ntStatus))
{
KDPRINT("【PrintLoadedModule】::【PrintAllLoadedMoudleByAux】AuxKlibQueryModuleInformation 2 Failed!\r\n");
break;
}
for (ULONG i = 0; i < ulNumberOfModules; i++)
{
KDPRINT("【PrintLoadedModule】::【PrintAllLoadedMoudleByAux】Path:%-50s BaseAddress:0x%p\r\n",
pModules[i].FullPathName, pModules[i].BasicInfo.ImageBase);
}
KDPRINT("【PrintLoadedModule】::【PrintAllLoadedMoudleByAux】共计%d个内核模块!\r\n", ulNumberOfModules);
}
} while (false);
if (pModules)
{
ExFreePoolWithTag(pModules, MmTagTypeAux);
}
return ntStatus;
}
5.运行结果
XP 32位
Win7 x64: