-
Two other methods are attached
1. Main differences
The functions or structures in the methods used in the above two links are not documented, so there are different structures or other definitions in different system environments, which may need to be obtained by targeted debugging of the system. The method described in the current document is documented.
2. Prototype
NTSTATUS AuxKlibQueryModuleInformation( PULONG BufferSize, ULONG ElementSize, PVOID QueryInfo );
Parameters:
- BufferSize [In/Out] A pointer to the size of the receive data buffer in bytes. If QueryInfo is empty, this value is the number of bytes of the size of the received information that the driver must allocate. If QueryInfo is not empty, it is the given buffer size.
- ElementSize[In] The QueryInfo pointer points to the byte size of each element in the array. The settable values are sizeof(AUX_MODULE_BASIC_INFO) or sizeof(AUX_MODULE_EXTENDED_INFO).
- QueryInfo [Out/Optional] points to the structure AUX_MODULE_BASIC_INFO perhaps AUX_MODULE_EXTENDED_INFO Array, which is used to receive information about the loaded module. If the pointer is null, AuxKlibQueryModuleInformation Writes the required buffer size to the BufferSize pointer
Return value:
Status will be returned if the operation is successful_ SUCCESS ;
If QueryInfo is not empty and the buffer provided by the driver is not large enough, status is returned_ BUFFER_ TOO_ SMALL ;
Other NTSTATUS values may also be returned.
remarks:
To obtain the system loading module information, the driver must do the following:
1. Call AuxKlibQueryModuleInformation and QueryInfo is null. After returning, BufferSize is the number of bytes of the buffer to be allocated.
2. Call a memory request routine, such as ExAllocatePoolWithTag, to allocate a buffer for the array.
3. Call AuxKlibQueryModuleInformation again. QueryInfo is the requested buffer address pointer. After AuxKlibQueryModuleInformation is returned, the buffer contains an array of loaded modules.
AuxKlibInitialize must be called before using AuxKlibQueryModuleInformation.
requirement:
Header file aux_klib.h (include Aux_klib.h)
Include library Aux_Klib.lib
3. Structure
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. Code implementation
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]total%d Kernel modules!\r\n", ulNumberOfModules); } } while (false); if (pModules) { ExFreePoolWithTag(pModules, MmTagTypeAux); } return ntStatus; }
5. Operation results
XP 32-bit
Win7 x64: