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_ENTRY64 的指针
typedef struct _LDR_DATA_TABLE_ENTRY64
{
LIST_ENTRY64 InLoadOrderLinks;
LIST_ENTRY64 InMemoryOrderLinks;
LIST_ENTRY64 InInitializationOrderLinks;
PVOID DllBase;
PVOID EntryPoint;
ULONG SizeOfImage;
UNICODE_STRING FullDllName;
UNICODE_STRING BaseDllName;
ULONG Flags;
USHORT LoadCount;
USHORT TlsIndex;
PVOID SectionPointer;
ULONG CheckSum;
PVOID LoadedImports;
PVOID EntryPointActivationContext;
PVOID PatchInformation;
LIST_ENTRY64 ForwarderLinks;
LIST_ENTRY64 ServiceTagLinks;
LIST_ENTRY64 StaticLinks;
PVOID ContextInformation;
ULONG64 OriginalBase;
LARGE_INTEGER LoadTime;
} LDR_DATA_TABLE_ENTRY64, *PLDR_DATA_TABLE_ENTRY64;
+0x000 InLoadOrderLinks : _LIST_ENTRY //驱动模块加载的顺序
4 +0x000 Flink : Ptr32
5 +0x004 Blink : Ptr32
6 +0x008 InMemoryOrderLinks : _LIST_ENTRY //模块在内存中的顺序 在驱动中为空
7 +0x000 Flink : Ptr32
8 +0x004 Blink : Ptr32
9 +0x010 InInitializationOrderLinks : _LIST_ENTRY //模块初始化的顺序 在驱动中为空
10 +0x000 Flink : Ptr32
11 +0x004 Blink : Ptr32
12 +0x018 DllBase : Ptr32
13 +0x01c EntryPoint : Ptr32
14 +0x020 SizeOfImage : Uint4B
15 +0x024 FullDllName : _UNICODE_STRING
16 +0x000 Length : Uint2B
17 +0x002 MaximumLength : Uint2B
18 +0x004 Buffer : Ptr32
19 +0x02c BaseDllName : _UNICODE_STRING
20 +0x000 Length : Uint2B
21 +0x002 MaximumLength : Uint2B
22 +0x004 Buffer : Ptr32
23 +0x034 Flags : Uint4B
24 +0x038 LoadCount : Uint2B
25 +0x03a TlsIndex : Uint2B
26 +0x03c HashLinks : _LIST_ENTRY
27 +0x000 Flink : Ptr32
28 +0x004 Blink : Ptr32
29 +0x03c SectionPointer : Ptr32
30 +0x040 CheckSum : Uint4B
31 +0x044 TimeDateStamp : Uint4B
32 +0x044 LoadedImports : Ptr32
33 +0x048 EntryPointActivationContext : Ptr32
34 +0x04c PatchInformation : Ptr32
遍历代码
#include<ntifs.h>
typedef struct _LDR_DATA_TABLE_ENTRY64
{
LIST_ENTRY64 InLoadOrderLinks;
LIST_ENTRY64 InMemoryOrderLinks;
LIST_ENTRY64 InInitializationOrderLinks;
PVOID DllBase;
PVOID EntryPoint;
ULONG SizeOfImage;
UNICODE_STRING FullDllName;
UNICODE_STRING BaseDllName;
ULONG Flags;
USHORT LoadCount;
USHORT TlsIndex;
PVOID SectionPointer;
ULONG CheckSum;
PVOID LoadedImports;
PVOID EntryPointActivationContext;
PVOID PatchInformation;
LIST_ENTRY64 ForwarderLinks;
LIST_ENTRY64 ServiceTagLinks;
LIST_ENTRY64 StaticLinks;
PVOID ContextInformation;
ULONG64 OriginalBase;
LARGE_INTEGER LoadTime;
} LDR_DATA_TABLE_ENTRY64, *PLDR_DATA_TABLE_ENTRY64;
VOID DriverUnload(PDRIVER_OBJECT DriverObject)
{
}
NTSTATUS GetSystemModuleInfo(PDRIVER_OBJECT DriverObject)
{
PLDR_DATA_TABLE_ENTRY64 pLDTE = NULL;
PLDR_DATA_TABLE_ENTRY64 pNextLDTE = NULL;
/*********** 变量申明在这上面************/
//DriverSection保存的是_LDR_DATA_TABLE_ENTRY 结构体的指针
//pLDTE 保存本模块的_LDR_DATA_TABLE_ENTRY指针
pLDTE = (PLDR_DATA_TABLE_ENTRY64)DriverObject->DriverSection;
//通过模块链表找到ntoskrnl.exe的位置
pNextLDTE = pLDTE;
do {
if (pNextLDTE->SizeOfImage != 0)
{
if (pNextLDTE->BaseDllName.Buffer[pNextLDTE->BaseDllName.Length / 2 - 3] == L'e'&&
pNextLDTE->BaseDllName.Buffer[pNextLDTE->BaseDllName.Length / 2 - 2] == L'x'&&
pNextLDTE->BaseDllName.Buffer[pNextLDTE->BaseDllName.Length /2 - 1] == L'e')
{
pLDTE = pNextLDTE;
break;
}
}
pNextLDTE = (PLDR_DATA_TABLE_ENTRY64)(((PLIST_ENTRY)pNextLDTE)->Flink);
} while (pLDTE != pNextLDTE);
//从系统模块开始遍历链表
do {
if (pNextLDTE->SizeOfImage != 0)
{
DbgPrint("模块名%wZ\n", &pNextLDTE->BaseDllName);
}
pNextLDTE = (PLDR_DATA_TABLE_ENTRY64)(((PLIST_ENTRY)pNextLDTE)->Flink);
} while (pLDTE != pNextLDTE);
return STATUS_SUCCESS;
}
NTSTATUS DriverEntry(
PDRIVER_OBJECT DriverObject, // 驱动对象,类似实例句柄
PUNICODE_STRING RegistryPath) // 字符串指针,保存驱动在注册表的路径
{
//设置回调函数
DbgPrint("驱动开始加载\n");
DriverObject->DriverUnload = DriverUnload;
GetSystemModuleInfo(DriverObject);
return STATUS_SUCCESS;
}
使用ZwQuerySystemInformation来遍历内核模块
typedef enum _SYSTEM_INFORMATION_CLASS
{
SystemModuleInformation = 11
}SYSTEM_INFORMATION_CLASS;
NTSTATUS ZwQuerySystemInformation(
IN ULONG SystemInformationClass,
OUT PVOID SystemInformation,
IN ULONG SystemInformationLength,
OUT PULONG ReturnLength);
typedef struct _SYSTEM_MODULE_INFORMATION_ENTRY {
HANDLE Section;
PVOID MappedBase;
PVOID Base;
ULONG Size;
ULONG Flags;
USHORT LoadOrderIndex;
USHORT InitOrderIndex;
USHORT LoadCount;
USHORT PathLength;
CHAR ImageName[256];
} SYSTEM_MODULE_INFORMATION_ENTRY, *PSYSTEM_MODULE_INFORMATION_ENTRY;
typedef struct _SYSTEM_MODULE_INFORMATION {
ULONG Count; //模块总个数 后面的全部都是SYSTEM_MODULE_INFORMATION_ENTRY结构 系统会把所有的模块信息都写在下面的数组里面
SYSTEM_MODULE_INFORMATION_ENTRY Module[1];
} SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_INFORMATION;
VOID EnumModule()
{
NTSTATUS status = STATUS_SUCCESS;
PSYSTEM_MODULE_INFORMATION pSysModInfo = (PSYSTEM_MODULE_INFORMATION)ExAllocatePoolWithTag(PagedPool, 0x1024 * 32, 'dale');
if (!pSysModInfo)
{
KdPrint(("内存分配失败\n"));
return;
}
RtlZeroMemory(pSysModInfo, 0x1024 * 32);
ULONG ulRet;
status = ZwQuerySystemInformation(SystemModuleInformation, pSysModInfo, 0x1024 * 32, &ulRet);
if (!NT_SUCCESS(status))
{
KdPrint(("枚举模块信息失败\n"));
}
for (ULONG i = 0; i < pSysModInfo->Count;i++)
{
KdPrint(("模块名%s\n 模块基址%p 模块大小0x%x\n",
pSysModInfo->Module[i].ImageName,
pSysModInfo->Module[i].Base,
pSysModInfo->Module[i].Size
));
}
}