驅動中遍歷模塊,以及獲取ntoskrnl.exe基址

方法是基於PsLoadModuleList方式spa

驅動中遍歷模塊

一丶簡介

簡介:3d

進入內核了.遍歷內核中使用的模塊該怎麼辦. 其實在驅動中.咱們的DriverEntry入口位置.
提供了兩個參數. 一個是DrIverObject另外一個則是註冊表路徑.code

其實遍歷模塊的技巧就在這個DriverObject中.對象

衆所周知在Ring3下遍歷模塊能夠經過TEB PEB遍歷. 咱們會接觸一個結構體叫作LDR_DATA_TABLE_ENTRY的結構體.
內核中也會使用這個結構體. 看下DriverObject對象所表明的含義.blog

typedef struct _DRIVER_OBJECT {
    CSHORT Type;
    CSHORT Size;

    PDEVICE_OBJECT DeviceObject;                //驅動對象
    ULONG Flags;                                //驅動的標誌


    PVOID DriverStart;                          //驅動的起始位置
    ULONG DriverSize;                           //驅動的大小
    PVOID DriverSection;                        //指向驅動程序映像的內存區對象
    PDRIVER_EXTENSION DriverExtension;          //驅動的擴展空間

    UNICODE_STRING DriverName;                  //驅動名字

    PUNICODE_STRING HardwareDatabase;


    PFAST_IO_DISPATCH FastIoDispatch;


    PDRIVER_INITIALIZE DriverInit;
    PDRIVER_STARTIO DriverStartIo;
    PDRIVER_UNLOAD DriverUnload;
    PDRIVER_DISPATCH MajorFunction[IRP_MJ_MAXIMUM_FUNCTION + 1];

} DRIVER_OBJECT;
typedef struct _DRIVER_OBJECT *PDRIVER_OBJECT;

在這裏主要使用 DriverSection這個成員 這個成員則能夠解釋爲LDR_DATA_TABLE_ENTRY結構體.
裏面存放着咱們的全部模塊.內存

typedef struct _LDR_DATA_TABLE_ENTRY {
    LIST_ENTRY InLoadOrderLinks;               //鏈表存儲,指向下一個LDR_DATA_TABLE_ENTRY結構
    LIST_ENTRY InMemoryOrderLinks;
    LIST_ENTRY InInitializationOrderLinks;
    PVOID DllBase;                             //基址
    PVOID EntryPoint;
    ULONG SizeOfImage;
    UNICODE_STRING FullDllName;
    UNICODE_STRING BaseDllName;                //存放着驅動模塊名
    ULONG Flags;
    USHORT LoadCount;
    USHORT TlsIndex;
    union {
        LIST_ENTRY HashLinks;
        struct {
            PVOID SectionPointer;
            ULONG CheckSum;
        };
    };
    union {
        struct {
            ULONG TimeDateStamp;
        };
        struct {
            PVOID LoadedImports;
        };
    };
}LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;

因此代碼就很簡單了.直接遍歷自身結構體的 DriverSection成員便可.解釋爲(LDR_DATA_TABLE_ENTRY)結構.it

二丶代碼以及演示.

#include "Driver.h" //這個替換爲本身的. 包含Ntddk.h便可.
#include <wdm.h>

//KLDR_DATA_TABLE_ENTRY

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;
    ULONG Flags;
    USHORT LoadCount;
    USHORT TlsIndex;
    union {
        LIST_ENTRY HashLinks;
        struct {
            PVOID SectionPointer;
            ULONG CheckSum;
        };
    };
    union {
        struct {
            ULONG TimeDateStamp;
        };
        struct {
            PVOID LoadedImports;
        };
    };
}LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;

NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObj, PUNICODE_STRING pRegPath)
{
    ULONG iCount = 0;
    NTSTATUS ntStatus;
    pDriverObj->DriverUnload = DriverUnLoad;

    KdBreakPoint();

    /*
    主要是遍歷DriverObject中的 DriverSection 它能夠解釋爲LDR_DATA_TABLE_ENTRY結構體
    */

    
    PLDR_DATA_TABLE_ENTRY pLdr = NULL;
    PLIST_ENTRY pListEntry = NULL;
    PLIST_ENTRY pCurrentListEntry = NULL;

    PLDR_DATA_TABLE_ENTRY pCurrentModule = NULL;
    pLdr = (PLDR_DATA_TABLE_ENTRY)pDriverObj->DriverSection;
    pListEntry = pLdr->InLoadOrderLinks.Flink;
    pCurrentListEntry = pListEntry->Flink;

    while (pCurrentListEntry != pListEntry) //先後不相等
    {
        //獲取LDR_DATA_TABLE_ENTRY結構
        pCurrentModule = CONTAINING_RECORD(pCurrentListEntry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
        
            if (pCurrentModule->BaseDllName.Buffer != 0)
            {
                DbgPrint("ModuleName = %wZ ModuleBase = %p \r\n", 
                    pCurrentModule->BaseDllName,
                 pCurrentModule->DllBase);
            }
            pCurrentListEntry = pCurrentListEntry->Flink;
    }
    return STATUS_SUCCESS;
}

結果.
io

代碼簡單改一下.還能夠得到指定的模塊的基址以及結束地址.ast

代碼以下class

VOID GetModuleBaseByName(PDRIVER_OBJECT pDriverObj,UNICODE_STRING ModuleName)
{
    PLDR_DATA_TABLE_ENTRY pLdr = NULL;
    PLIST_ENTRY pListEntry = NULL;
    PLIST_ENTRY pCurrentListEntry = NULL;

    PLDR_DATA_TABLE_ENTRY pCurrentModule = NULL;
    pLdr = (PLDR_DATA_TABLE_ENTRY)pDriverObj->DriverSection;
    pListEntry = pLdr->InLoadOrderLinks.Flink;
    pCurrentListEntry = pListEntry->Flink;

    while (pCurrentListEntry != pListEntry) //先後不相等
    {
        //獲取LDR_DATA_TABLE_ENTRY結構
        pCurrentModule = CONTAINING_RECORD(pCurrentListEntry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);

        if (pCurrentModule->BaseDllName.Buffer != 0)
        {
        
            if (RtlCompareUnicodeString(&pCurrentModule->BaseDllName, &ModuleName, TRUE) == 0)
            {
                DbgPrint("ModuleName = %wZ ModuleBase = %p ModuleEndBase = %p\r\n",
                    pCurrentModule->BaseDllName,
                    pCurrentModule->DllBase,
                    (LONGLONG)pCurrentModule->DllBase + pCurrentModule->SizeOfImage);
            }
            
        }
        pCurrentListEntry = pCurrentListEntry->Flink;
    }
}
相關文章
相關標籤/搜索