windows驱动

驱动基础

驱动

驱动环境

因为老早前就整过驱动了,环境重新搭了下。

这边是win10专业版,虚拟机也是win10专业版

image-20200705145916994

image-20200707153903687

image-20200707153922061

首先配置调试环境,这边按图设置一波就行

然后是软件配置这边安利俩个工具DriverMonitor和Dbgview,记得用管理员权限打开

image-20200705151121257

驱动代码如下

image-20200705151216292

就成功了,如果报错签名问题的话重启电脑在启动设置那边禁用驱动签名

image-20200705150932187

但是这是一次性的重启一次就不行了

需要永久禁用驱动签名的话输入bcdedit -set {default} TESTSIGNING on来启动测试模式

image-20200706134904077

再说说调试
image-20200707154727646

遇到符号路径问题输入

! sym

.reload

即可

驱动模块知识

1
2
3
4
5
6
7
8
9
10
11
12
#include <ntddk.h>
VOID Unload(IN PDRIVER_OBJECT pDriverObject)
{
return STATUS_SUCCESS;
}

NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObject, IN PUNICODE_STRING RegistryPath) {
DbgPrint("%p,%wZ", pDriverObject, RegistryPath);
pDriverObject->DriverUnload = Unload;
return STATUS_SUCCESS;

}

编译加载,dbgview查看

FFFF870B6A6A8E30,\REGISTRY\MACHINE\SYSTEM\ControlSet001\Services\Kernel_learning

windbg查看对应结构体_driver_object

image-20200711201509953

可以看到我们加载驱动的许多信息

再看看ldr,这个和三环peb的很像,在三环隐藏进程需要断链断三个,0环order和init不使用,所以只有第一个加载顺序,把所有内核模块都存在一个链表里,我们可以通过这个遍历所有内核模块

image-20200711235534638

可以看到内核文件还有硬件抽象层dll

接下去尝试一波写代码遍历所有内核模块,成果如下

image-20200712002747826

代码如下(把驱动名改成模块名更准确些,但就不钻牛角尖了)

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
#include <ntddk.h>

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;

VOID Unload(IN PDRIVER_OBJECT pDriverObject)
{
return STATUS_SUCCESS;
}

NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObject, IN PUNICODE_STRING RegistryPath) {
LDR_DATA_TABLE_ENTRY* fuck1, * fuck2;
fuck1 = (LDR_DATA_TABLE_ENTRY*)pDriverObject->DriverSection;
//DbgPrint("驱动名%wZ\n", &fuck1->FullDllName);
PLIST_ENTRY fuck3;
fuck3 = fuck1->InLoadOrderLinks.Flink;
while (TRUE)
{
fuck2 = (LDR_DATA_TABLE_ENTRY*)fuck3;
DbgPrint("驱动名%wZ\n", &fuck2->FullDllName);
fuck3 = fuck3->Flink;
if (fuck3 == &fuck1->InLoadOrderLinks)
{
fuck2 = (LDR_DATA_TABLE_ENTRY*)fuck3;
DbgPrint("驱动名%wZ\n", &fuck2->FullDllName);
break;
}
}

pDriverObject->DriverUnload = Unload;
return STATUS_SUCCESS;

}

当然与三环相对应也能进行模块隐藏,三环只需要断链三个链表,0环除了做这个还有一个二叉平衡树需要操作

再来一波常规的驱动编程,其实驱动编程很win32控件很像,在win32控件中消息循环对不同消息做不同处理,而在内核中则是一个新的封装的结构体叫做IRP,在消息循环中消息对应窗口对象而在内核中则是设备对象。如果熟悉win32消息处理机制的话学起来其实特别轻松

基本编程思路是

1.创建设备对象

2.规定通信方式

3.注册符号链接

4.注册irp处理函数

5.编写irp处理函数

文章目录
  1. 1. 驱动
    1. 1.1. 驱动环境
    2. 1.2. 驱动模块知识
|