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


方法是基於PsLoadModuleList方式

驅動中遍歷模塊

一丶簡介

簡介:

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

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

眾所周知在Ring3下遍歷模塊可以通過TEB PEB遍歷. 我們會接觸一個結構體叫做LDR_DATA_TABLE_ENTRY的結構體.
內核中也會使用這個結構體. 看下DriverObject對象所代表的含義.


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)結構.

二丶代碼以及演示.

#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;
}

結果.

代碼簡單改一下.還可以獲得指定的模塊的基址以及結束地址.

代碼如下

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;
	}
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM