【火哥学习笔记】通过链表找出所有已注册的驱动

_DRIVER_OBJECT结构如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
nt!_DRIVER_OBJECT
+0x000 Type : 0n4
+0x002 Size : 0n168
+0x004 DeviceObject : (null)
+0x008 Flags : 0x12
+0x00c DriverStart : 0x9e0a0000 Void
+0x010 DriverSize : 0x6000
+0x014 DriverSection : 0x8b9a8510 Void
+0x018 DriverExtension : 0xa31efcd8 _DRIVER_EXTENSION
+0x01c DriverName : _UNICODE_STRING "\Driver\HelloDriver_Service"
+0x024 HardwareDatabase : 0x82078338 _UNICODE_STRING "\REGISTRY\MACHINE\HARDWARE\DESCRIPTION\SYSTEM"
+0x028 FastIoDispatch : (null)
+0x02c DriverInit : 0x9e0a1090 long HelloDriver!FxDriverEntry+0
+0x030 DriverStartIo : (null)
+0x034 DriverUnload : 0x9e0a1050 void HelloDriver!DriverUnload+0
+0x038 MajorFunction : [28] 0x81b1c89c long nt!IopInvalidDeviceRequest+0

HardwareDatabase是驱动的注册路径(注册表路径)

偏移为 +0x014DriverSection 对应的地址结构为 _LDR_DATA_TABLE_ENTRY ;其部分结构如下

1
2
3
4
5
6
7
8
9
10
11
nt!_LDR_DATA_TABLE_ENTRY
+0x000 InLoadOrderLinks : _LIST_ENTRY [ 0x81cb6678 - 0xad4fe3b8 ]
+0x008 InMemoryOrderLinks : _LIST_ENTRY [ 0xffffffff - 0xffffffff ]
+0x010 InInitializationOrderLinks : _LIST_ENTRY [ 0x0 - 0x0 ]
+0x018 DllBase : 0x9e0a0000 Void
+0x01c EntryPoint : 0x9e0a1090 Void
+0x020 SizeOfImage : 0x6000
+0x024 FullDllName : _UNICODE_STRING "\??\C:\Users\papayo\Desktop\HelloDriver.sys"
+0x02c BaseDllName : _UNICODE_STRING "HelloDriver.sys"
+0x034 FlagGroup : [4] ""
+0x034 Flags : 0x49104000

InLoadOrderLinks就是所有驱动首地址构成的链表 BaseDllName是驱动文件名 FullDllName是驱动文件路径

知道找到循环链表的途径了,写代码跑出所有的驱动

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <ntddk.h>
VOID DriverUnload(PDRIVER_OBJECT driver)
{
DbgPrint("卸载了\n");
}
NTSTATUS DriverEntry(PDRIVER_OBJECT driver, PUNICODE_STRING reg_path)
{
DbgPrint("hello world!\n");
DbgPrint("注册表路径:%wZ\n", reg_path);
DbgPrint("驱动物理地址:%X\n", (int)driver);
void* p = *(int*)((int)driver + 0x014);
DbgPrint("DriverSection:%X\n", (int)p);
do
{
PUNICODE_STRING name = (int*)((int)p + 0x02c);
DbgPrint("nameaddr : %X\n", (int)name);
DbgPrint("模块:%ws \t\t 物理地址:%X\n", name->Buffer, (int)p);
p = (void*)*((int*)p);
} while ((int)p != *(int*)((int)driver + 0x014));
driver->DriverUnload = DriverUnload;
return STATUS_SUCCESS;
}