抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

驱动开发

知识点

驱动是进程吗

驱动并不是进程, 而是叫模块(本质上和dll是一样的);

驱动类型

NT: NT4虚拟驱动(现在基本没有纯NT4的驱动);
WDM: 是一个热拔插方式;
WDF: 简化开发, 相当于事件驱动机制; KWDF(内核驱动框架), UWDF(用户驱动框架);

加载驱动

  1. 服务加载
    OpenSrcManager
    CreateService
    StartService
    StopService
    DeleteService
  1. 本地加载
    Zw/NtLoadDriver
    Zw/NtUnloadDriver

驱动基础

知识点

类型

int => INT short => SHORT long => LONG

字符串函数, 申请内存函数

字符串操作

  1. RtlInitString: 初始化多字节ascii
  1. RtlInitUnicodeString: 初始化宽字符
  1. RtlFreeUnicodeString: 释放unicode字符串
  1. RtlStringCbPrintfA: 格式化输出, 引用#include <ntstrsafe.h>
  1. RtlCompareUnicodeString: 字符串比较

内存操作

  1. ExAllocatePool(内存申请)
    NonPagedPool => 非分页内存(带执行属性)
    PagedPool => 分页内存(不带执行属性)
  1. ExFreePool(释放内存)

创建线程

  1. PsCreateSystemThread(创建线程)
1
2
3
4
5
6
7
8
9
10
11
12
// 回调函数
VOID work(PVOID StartContext)
{

}

HANDLE hThread = NULL;
NTSTATUS status = PsCreateSystemThread(&hThread, THREAD_ALL_ACCESS, NULL, NULL, NULL, work, NULL);
if (NT_SUCCESS(status))
{
ZwClose(hThread);
}

普通链表

API

InitializeListHead(初始化链表)
IsListEmpty(判断链表是否为空)
InsertHeadList(链表头部插入数据)
InsertTailList(链表尾部插入数据)
RemoveHeadList(移除链表头部数据)
RemoveTailList(移除链表尾部数据)
RemoveEntryList(移除空链表)

驱动遍历

代码实验

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#include <ntifs.h>

typedef struct _KLDR_DATA_TABLE_ENTRY {
LIST_ENTRY InLoadOrderLinks;
ULONG __Undefined1;
ULONG __Undefined2;
ULONG __Undefined3;
ULONG NonPagedDebugInfo;
ULONG DllBase;
ULONG EntryPoint;
ULONG SizeOfImage;
UNICODE_STRING FullDllName;
UNICODE_STRING BaseDllName;
ULONG Flags;
USHORT LoadCount;
USHORT __Undefined5;
ULONG __Undefined6;
ULONG CheckSum;
ULONG TimeDateStamp;

} KLDR_DATA_TABLE_ENTRY, *PKLDR_DATA_TABLE_ENTRY;

void DriverUnload(PDRIVER_OBJECT pDriver)
{
DbgPrintEx(77, 0, "-----------DriverUnload-----------");
}

NTSTATUS DriverEntry(PDRIVER_OBJECT pDriver, PUNICODE_STRING pReg)
{
// DbgBreakPoint();
// 遍历驱动
PKLDR_DATA_TABLE_ENTRY ldr = (PKLDR_DATA_TABLE_ENTRY)pDriver->DriverSection;
PKLDR_DATA_TABLE_ENTRY pre = (PKLDR_DATA_TABLE_ENTRY)ldr->InLoadOrderLinks.Flink;
PKLDR_DATA_TABLE_ENTRY next = (PKLDR_DATA_TABLE_ENTRY)pre->InLoadOrderLinks.Flink;

while (next != pre)
{
DbgPrintEx(77, 0, "[db]: Driver Name = %wZ\r\n", &next->FullDllName);
next = (PKLDR_DATA_TABLE_ENTRY)next->InLoadOrderLinks.Flink;
}

pDriver->DriverUnload = DriverUnload;
return STATUS_SUCCESS;
}

驱动断链

结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
kd> dt _DRIVER_OBJECT
ntdll!_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 // 链表
+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

实验代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
#include <ntifs.h>

typedef struct _KLDR_DATA_TABLE_ENTRY {
LIST_ENTRY InLoadOrderLinks;
ULONG __Undefined1;
ULONG __Undefined2;
ULONG __Undefined3;
ULONG NonPagedDebugInfo;
ULONG DllBase;
ULONG EntryPoint;
ULONG SizeOfImage;
UNICODE_STRING FullDllName;
UNICODE_STRING BaseDllName;
ULONG Flags;
USHORT LoadCount;
USHORT __Undefined5;
ULONG __Undefined6;
ULONG CheckSum;
ULONG TimeDateStamp;

} KLDR_DATA_TABLE_ENTRY, *PKLDR_DATA_TABLE_ENTRY;

NTKERNELAPI NTSTATUS ObReferenceObjectByName(
__in PUNICODE_STRING ObjectName,
__in ULONG Attributes,
__in_opt PACCESS_STATE AccessState,
__in_opt ACCESS_MASK DesiredAccess,
__in POBJECT_TYPE ObjectType,
__in KPROCESSOR_MODE AccessMode,
__inout_opt PVOID ParseContext,
__out PVOID *Object
);

extern POBJECT_TYPE * IoDriverObjectType;

void DriverHide(PWCH wcObjectName)
{
LARGE_INTEGER in = { 0 };
in.QuadPart = -10000 * 5000;
KeDelayExecutionThread(KernelMode, FALSE, &in);
UNICODE_STRING usDriverName = { 0 };
RtlInitUnicodeString(&usDriverName, wcObjectName);
PDRIVER_OBJECT pDriverObject = NULL;
NTSTATUS status = ObReferenceObjectByName(&usDriverName, FILE_ALL_ACCESS, 0, 0, IoDriverObjectType, KernelMode, NULL, &pDriverObject);
if (NT_SUCCESS(status))
{
PKLDR_DATA_TABLE_ENTRY ldr = (PKLDR_DATA_TABLE_ENTRY)pDriverObject->DriverSection;
DbgPrintEx(77, 0, "[db]: Driver Name = %wZ\r\n", &ldr->FullDllName);
// pDriverObject->DriverSection = ldr->InLoadOrderLinks.Flink; // 修复pc hunter 卡死(移花接木)
RemoveEntryList(&ldr->InLoadOrderLinks);
pDriverObject->DriverInit = NULL;
pDriverObject->DriverSection = NULL;
ObDereferenceObject(pDriverObject); // 引用计数清除
}
else
{
DbgPrintEx(77, 0, "DriverHide ObReferenceObjectByName Failed");
}
return;
}

void DriverUnload(PDRIVER_OBJECT pDriver)
{
DbgPrintEx(77, 0, "-----------DriverUnload-----------");
}

NTSTATUS DriverEntry(PDRIVER_OBJECT pDriver, PUNICODE_STRING pReg)
{
// 断链隐藏自身
HANDLE hThread = NULL;
NTSTATUS status = PsCreateSystemThread(&hThread, THREAD_ALL_ACCESS, NULL, NULL, NULL, DriverHide, "\\drivers\\MyDriver3");
if (NT_SUCCESS(status))
{
NtClose(hThread);
}
// 有BUG
/*
DbgBreakPoint();
PKLDR_DATA_TABLE_ENTRY ldr = (PKLDR_DATA_TABLE_ENTRY)pDriver->DriverSection;
PKLDR_DATA_TABLE_ENTRY pre = (PKLDR_DATA_TABLE_ENTRY)ldr->InLoadOrderLinks.Flink;
PKLDR_DATA_TABLE_ENTRY next = (PKLDR_DATA_TABLE_ENTRY)pre->InLoadOrderLinks.Flink;

UNICODE_STRING usDriverName1 = { 0 };
RtlInitUnicodeString(&usDriverName1, L"\\drivers\\http");

UNICODE_STRING usDriverName = { 0 };
RtlInitUnicodeString(&usDriverName, L"http.sys");

while (next != pre)
{
// DbgPrintEx(77, 0, "[db]: Driver Name = %wZ\r\n", &next->FullDllName);
if (next->BaseDllName.Length != 0 && RtlCompareUnicodeString(&usDriverName, &next->BaseDllName, TRUE) == 0)
{
PDRIVER_OBJECT pDriverObject = NULL;
NTSTATUS status = ObReferenceObjectByName(&usDriverName1, FILE_ALL_ACCESS, 0, 0, IoDriverObjectType, KernelMode, NULL, &pDriverObject);
if (NT_SUCCESS(status))
{
pDriverObject->DriverInit = NULL;
pDriverObject->DriverSection = NULL;
// pDriverObject->Type = 0; // 规避暴露搜索
}
else
{
DbgPrintEx(77, 0, "DriverHide ObReferenceObjectByName Failed");
}
DbgPrintEx(77, 0, "[db]: Driver Name = %wZ\r\n", &next->FullDllName);
RemoveEntryList(&next->InLoadOrderLinks);
break;
}
next = (PKLDR_DATA_TABLE_ENTRY)next->InLoadOrderLinks.Flink;
}
*/
pDriver->DriverUnload = DriverUnload;
return STATUS_SUCCESS;
}

评论