PsLoadedModuleList是系统的一个全局变量,它指向一个保存着所加载驱动信息的双向链表。通过它可以枚举系统中所有的驱动模块。
这个双向链表的结构如下:
kd> dt _LIST_ENTRY nt!_LIST_ENTRY +0x000 Flink : Ptr32 _LIST_ENTRY //指向后一个链表 +0x004 Blink : Ptr32 _LIST_ENTRY //指向前一个链表
每一个驱动对象都存在这样一个结构.我们先看_DRIVER_OBJECT的结构
kd> dt _DRIVER_OBJECT nt!_DRIVER_OBJECT +0x000 Type : Int2B +0x002 Size : Int2B +0x004 DeviceObject : Ptr32 _DEVICE_OBJECT //设备对象 +0x008 Flags : Uint4B +0x00c DriverStart : Ptr32 Void //驱动对象起始地址 +0x010 DriverSize : Uint4B //驱动对象的大小 +0x014 DriverSection : Ptr32 Void //**这个实际上是一个LDR_DATA_TABLE_ENTRY 指针 +0x018 DriverExtension : Ptr32 _DRIVER_EXTENSION +0x01c DriverName : _UNICODE_STRING //驱动对象的名字 +0x024 HardwareDatabase : Ptr32 _UNICODE_STRING +0x028 FastIoDispatch : Ptr32 _FAST_IO_DISPATCH +0x02c DriverInit : Ptr32 long +0x030 DriverStartIo : Ptr32 void +0x034 DriverUnload : Ptr32 void +0x038 MajorFunction : [28] Ptr32 long
LDT_DATA_TABLE_ENTRY结构中的第一项就是LIST_ENTRY结构.这个LIST_ENTRY结构就是加载的驱动模块的链表
kd> dt _LDR_DATA_TABLE_ENTRY nt!_LDR_DATA_TABLE_ENTRY +0x000 InLoadOrderLinks : _LIST_ENTRY //驱动加载链表 +0x008 InMemoryOrderLinks : _LIST_ENTRY +0x010 InInitializationOrderLinks : _LIST_ENTRY +0x018 DllBase : Ptr32 Void +0x01c EntryPoint : Ptr32 Void +0x020 SizeOfImage : Uint4B +0x024 FullDllName : _UNICODE_STRING +0x02c BaseDllName : _UNICODE_STRING +0x034 Flags : Uint4B +0x038 LoadCount : Uint2B +0x03a TlsIndex : Uint2B +0x03c HashLinks : _LIST_ENTRY +0x03c SectionPointer : Ptr32 Void +0x040 CheckSum : Uint4B +0x044 TimeDateStamp : Uint4B +0x044 LoadedImports : Ptr32 Void +0x048 EntryPointActivationContext : Ptr32 Void +0x04c PatchInformation : Ptr32 Void
通过这三个结构的分析,我们就弄清楚了.
DRIVER_OBJECT +0x14 就得到了LIST_ENTRY 链表,通过对这个链表的遍历就能得到所有的驱动模块
//头文件 typedef struct { LIST_ENTRY InLoadOrderLink; LIST_ENTRY InMemoryOrderLinks; LIST_ENTRY InInitializationOrderLinks; PVOID DllBase; PVOID EntryPoint; ULONG SizeOfImage; UNICODE_STRING FullDllName; UNICODE_STRING BaseDllName; ULONG Flags; USHORT LoadCount; USHORT TlsIndex; LIST_ENTRY HashLinks; PVOID SectionPointer; ULONG CheckSum; ULONG TimeDateStamp; PVOID LoadedImports; PVOID EntryPointActivationContext; PVOID PatchInformation; }LDR_DATA_TABLE_ENTRY,*PLDR_DATA_TABLE_ENTRY;
代码:
#include "ntddk.h" #include "rootkit.h" void OnUnload(PDRIVER_OBJECT pDriverObj) { DbgPrint("Driver is Unload!\n"); } NTSTATUS DriverEntry(PDRIVER_OBJECT pRootkitObj,PUNICODE_STRING pRegistPath) { PLDR_DATA_TABLE_ENTRY pDriverList; PLIST_ENTRY pCurrentList; pRootkitObj->DriverUnload=OnUnload; pDriverList=(PLDR_DATA_TABLE_ENTRY) (pRootkitObj->DriverSection); pCurrentList=(PLIST_ENTRY) pDriverList; while (((PLIST_ENTRY)pDriverList)->Blink!=pCurrentList) { DbgPrint("DriverBase=0x%08X \tDriverSize 0x%08X \tDriverName=%ws\n", pDriverList->DllBase, pDriverList->SizeOfImage, (pDriverList->BaseDllName).Buffer); pDriverList=((PLIST_ENTRY)pDriverList)->Blink; } return STATUS_SUCCESS; }