Windows driver development learning record - traversing the third loaded module of the kernel (using AuxKlib)

Keywords: C++ Windows

  • Two other methods are attached

Windows driver development learning record - traversing one of the loaded modules of the kernel (using DriverSection)

Windows driver development learning record - traversing the second loaded module of the kernel (using zwquerysysteminsystem information)

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:

Posted by ghjr on Wed, 13 Oct 2021 22:05:03 -0700