【驱动学习】10-驱动开发通用模板

文章目录
  1. 1. 模板说明

概述:驱动开发通用模板

模板说明

内核中执行代码后需要将结果动态显示给应用层的用户,DeviceIoControl 是直接发送控制代码到指定的设备驱动程序,使相应的移动设备以执行相应的操作的函数,如下代码是一个经典的驱动开发模板框架,在开发经典驱动时会用到的一个通用案例。

如下这段案例中,我们只介绍DispatchIoctl,该函数主要用于接收或发送IOCTL控制信号,以此来实现接收和发送数据。

首先,通过调用IoGetCurrentIrpStackLocation函数获取IRP(I/O Request Packet)的堆栈位置,并获取控制码、输入和输出缓冲区的相关信息。

然后,根据不同的控制信号码,进行相应的处理流程。这里的示例代码只列出了一个控制信号码(IOCTL_IO_LyShark)的处理流程,即接收传入数据,进行处理后返回传出数据。

最后,根据处理结果,设置IRP的状态和返回信息,并通过调用IoCompleteRequest函数完成IRP的处理。

需要注意的是,这段代码中没有对错误情况进行处理,如果出现错误,返回的状态码为STATUS_INVALID_DEVICE_REQUEST。因此,实际使用中需要根据具体情况进行修改和完善。

如下所示,为驱动开发通用模板:

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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
#include <ntifs.h>
#include <windef.h>

// 控制器
#define IOCTL_IO_LyShark CTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_ANY_ACCESS)

// 卸载驱动执行
VOID UnDriver(PDRIVER_OBJECT pDriver)
{
PDEVICE_OBJECT pDev; // 用来取得要删除设备对象
UNICODE_STRING SymLinkName; // 局部变量symLinkName
pDev = pDriver->DeviceObject;
IoDeleteDevice(pDev); // 调用IoDeleteDevice用于删除设备
RtlInitUnicodeString(&SymLinkName, L"\\??\\LySharkDriver"); // 初始化字符串将symLinkName定义成需要删除的符号链接名称
IoDeleteSymbolicLink(&SymLinkName); // 调用IoDeleteSymbolicLink删除符号链接
DbgPrint("驱动卸载完毕...");
}

// 创建设备连接
NTSTATUS CreateDriverObject(IN PDRIVER_OBJECT pDriver)
{
NTSTATUS Status;
PDEVICE_OBJECT pDevObj;
UNICODE_STRING DriverName;
UNICODE_STRING SymLinkName;

// 创建设备名称字符串
RtlInitUnicodeString(&DriverName, L"\\Device\\LySharkDriver");
Status = IoCreateDevice(pDriver, 0, &DriverName, FILE_DEVICE_UNKNOWN, 0, TRUE, &pDevObj);

// 指定通信方式为缓冲区
pDevObj->Flags |= DO_BUFFERED_IO;

// 创建符号链接
RtlInitUnicodeString(&SymLinkName, L"\\??\\LySharkDriver");
Status = IoCreateSymbolicLink(&SymLinkName, &DriverName);
return STATUS_SUCCESS;
}

// 创建回调函数
NTSTATUS DispatchCreate(PDEVICE_OBJECT pDevObj, PIRP pIrp)
{
pIrp->IoStatus.Status = STATUS_SUCCESS; // 返回成功
DbgPrint("派遣函数 IRP_MJ_CREATE 执行 \n");
IoCompleteRequest(pIrp, IO_NO_INCREMENT); // 指示完成此IRP
return STATUS_SUCCESS; // 返回成功
}

// 关闭回调函数
NTSTATUS DispatchClose(PDEVICE_OBJECT pDevObj, PIRP pIrp)
{
pIrp->IoStatus.Status = STATUS_SUCCESS; // 返回成功
DbgPrint("派遣函数 IRP_MJ_CLOSE 执行 \n");
IoCompleteRequest(pIrp, IO_NO_INCREMENT); // 指示完成此IRP
return STATUS_SUCCESS; // 返回成功
}

// 主控制器,用于判断R3发送的控制信号
NTSTATUS DispatchIoctl(PDEVICE_OBJECT pDevObj, PIRP pIrp)
{
NTSTATUS status = STATUS_INVALID_DEVICE_REQUEST;
PIO_STACK_LOCATION pIrpStack;
ULONG uIoControlCode;
PVOID pIoBuffer;
ULONG uInSize;
ULONG uOutSize;

// 获得IRP里的关键数据
pIrpStack = IoGetCurrentIrpStackLocation(pIrp);

// 获取控制码
uIoControlCode = pIrpStack->Parameters.DeviceIoControl.IoControlCode;

// 输入和输出的缓冲区(DeviceIoControl的InBuffer和OutBuffer都是它)
pIoBuffer = pIrp->AssociatedIrp.SystemBuffer;

// EXE发送传入数据的BUFFER长度(DeviceIoControl的nInBufferSize)
uInSize = pIrpStack->Parameters.DeviceIoControl.InputBufferLength;

// EXE接收传出数据的BUFFER长度(DeviceIoControl的nOutBufferSize)
uOutSize = pIrpStack->Parameters.DeviceIoControl.OutputBufferLength;

// 对不同控制信号的处理流程
switch (uIoControlCode)
{
// 接收或发送
case IOCTL_IO_LyShark:
{
DWORD dw = 0;

// 得到输入参数
memcpy(&dw, pIoBuffer, sizeof(DWORD));

DbgPrint("[+] hello lyshark \n");

// 对输入参数进行处理
dw++;

// 设置输出参数
memcpy(pIoBuffer, &dw, sizeof(DWORD));

// 返回通信状态
status = STATUS_SUCCESS;
break;
}

pIrp->IoStatus.Status = status;
pIrp->IoStatus.Information = uOutSize;
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return status;
}

// 设定DeviceIoControl的*lpBytesReturned的值(如果通信失败则返回0长度)
if (status == STATUS_SUCCESS)
pIrp->IoStatus.Information = uOutSize;
else
pIrp->IoStatus.Information = 0;

// 设定DeviceIoControl的返回值是成功还是失败
pIrp->IoStatus.Status = status;
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return status;
}

// 入口函数
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriver, PUNICODE_STRING RegistryPath)
{
// 调用创建设备
CreateDriverObject(pDriver);

pDriver->DriverUnload = UnDriver; // 卸载函数
pDriver->MajorFunction[IRP_MJ_CREATE] = DispatchCreate; // 创建派遣函数
pDriver->MajorFunction[IRP_MJ_CLOSE] = DispatchClose; // 关闭派遣函数
pDriver->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchIoctl; // 分发函数

DbgPrint("By:LyShark ...");

return STATUS_SUCCESS;
}