驱动相关

runwu2204 Lv6

sys

sys也可以认为是一种dll(动态链接库) 其entry_point实际上就是DriverEntry,只不过内部进行了相应的注册和一些函数回调绑定

DriverEntry

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
NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath) {
UNREFERENCED_PARAMETER(RegistryPath);
//下面为IRP请求包对应的不同行为,相当于程序与驱动之间的通讯部分进行的调用
//绑定对应的行为,例如发生了IRP_MJ_CREATE操作就执行MyDriver_CreateClose
DriverObject->MajorFunction[IRP_MJ_CREATE] = MyDriver_CreateClose;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = MyDriver_CreateClose;
DriverObject->MajorFunction[IRP_MJ_READ] = MyDriver_ReadWrite;
DriverObject->MajorFunction[IRP_MJ_WRITE] = MyDriver_ReadWrite;
//字符串转换
RtlInitUnicodeString(&deviceNameUnicodeString, DEVICE_NAME);
RtlInitUnicodeString(&symbolicLinkUnicodeString, LINK_NAME);
//定义见下面代码
NTSTATUS status = IoCreateDevice(//获取对应设备句柄
DriverObject,
0,
&deviceNameUnicodeString,
FILE_DEVICE_UNKNOWN,
FILE_DEVICE_SECURE_OPEN,
FALSE,
&g_MyDeviceObject
);

if (!NT_SUCCESS(status)) {
return status;
}

status = IoCreateSymbolicLink(&symbolicLinkUnicodeString, &deviceNameUnicodeString);

if (!NT_SUCCESS(status)) {
IoDeleteDevice(g_MyDeviceObject);
return status;
}

return STATUS_SUCCESS;
}

IoCreateDevice

PDRIVER_OBJECT DEVICE_TYPE

1
2
3
4
5
6
7
8
9
NTSTATUS IoCreateDevice(
[in] PDRIVER_OBJECT DriverObject,//驱动对象
[in] ULONG DeviceExtensionSize,//驱动需要的额外空间
[in, optional] PUNICODE_STRING DeviceName,//驱动名
[in] DEVICE_TYPE DeviceType,//驱动类型
[in] ULONG DeviceCharacteristics,//
[in] BOOLEAN Exclusive,//
[out] PDEVICE_OBJECT *DeviceObject//输出对应的驱动对象
);

用于创建跟device的链接,等效于device name(device name只能在内核中调用,所以在用户态调用时需要创建SymbolicLink)

1
2
3
4
NTSTATUS IoCreateSymbolicLink(
[in] PUNICODE_STRING SymbolicLinkName,
[in] PUNICODE_STRING DeviceName
);

majorfunction

1
2
3
4
5
6
7
8
9
_Use_decl_annotations_
NTSTATUS
DispatchXxx(
struct _DEVICE_OBJECT *DeviceObject,
struct _IRP *Irp
)
{
// Function body
}

IRP结构

IRP请求分类

名称 描述 调用者
IRP_MJ_CREATE 请求句柄 CreateFile 0x00
IRP_MJ_CREATE_NAMED_PIPE 0x01
IRP_MJ_CLEANUP CloseHandle 0x12
IRP_MJ_CLOSE 关闭句柄 CloseHandle 0x02
IRP_MJ_READ 从设备输入数据 ReadFile 0x03
IRP_MJ_WRITE 输出数据到设备 WriteFile 0x04
IRP_MJ_DEVICE_CONTROL 控制操作(利用IOCTL) DeviceIoControl 0x0e
IRP_MJ_INTERNAL_DEVICE_CONTROL 控制操作(内核操作) 0x0f
IRP_MJ_QUERY_INFORMATION 得到文件的长度 GetFileSize 0x05
IRP_MJ_SET_INFORMATION 设置文件长度 SetFileSize 0x06
IRP_MJ_FLUSH_BUFFERS 写入或者丢弃缓冲区 FlushFileBuffers/FlushConsoleInputBuffer/PurgeComm 0x09
IRP_MJ_SHUTDOWN 系统关机 InitiateSystemShutdown 0x10
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
#define IRP_MJ_CREATE                   0x00
#define IRP_MJ_CREATE_NAMED_PIPE 0x01
#define IRP_MJ_CLOSE 0x02
#define IRP_MJ_READ 0x03
#define IRP_MJ_WRITE 0x04
#define IRP_MJ_QUERY_INFORMATION 0x05
#define IRP_MJ_SET_INFORMATION 0x06
#define IRP_MJ_QUERY_EA 0x07
#define IRP_MJ_SET_EA 0x08
#define IRP_MJ_FLUSH_BUFFERS 0x09
#define IRP_MJ_QUERY_VOLUME_INFORMATION 0x0a
#define IRP_MJ_SET_VOLUME_INFORMATION 0x0b
#define IRP_MJ_DIRECTORY_CONTROL 0x0c
#define IRP_MJ_FILE_SYSTEM_CONTROL 0x0d
#define IRP_MJ_DEVICE_CONTROL 0x0e
#define IRP_MJ_INTERNAL_DEVICE_CONTROL 0x0f
#define IRP_MJ_SHUTDOWN 0x10
#define IRP_MJ_LOCK_CONTROL 0x11
#define IRP_MJ_CLEANUP 0x12
#define IRP_MJ_CREATE_MAILSLOT 0x13
#define IRP_MJ_QUERY_SECURITY 0x14
#define IRP_MJ_SET_SECURITY 0x15
#define IRP_MJ_POWER 0x16
#define IRP_MJ_SYSTEM_CONTROL 0x17
#define IRP_MJ_DEVICE_CHANGE 0x18
#define IRP_MJ_QUERY_QUOTA 0x19
#define IRP_MJ_SET_QUOTA 0x1a
#define IRP_MJ_PNP 0x1b
#define IRP_MJ_PNP_POWER IRP_MJ_PNP // Obsolete....
#define IRP_MJ_MAXIMUM_FUNCTION 0x1b

相关类型定义

DEVICE_TYPE

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
#define FILE_DEVICE_8042_PORT           0x00000027
#define FILE_DEVICE_ACPI 0x00000032
#define FILE_DEVICE_BATTERY 0x00000029
#define FILE_DEVICE_BEEP 0x00000001
#define FILE_DEVICE_BUS_EXTENDER 0x0000002a
#define FILE_DEVICE_CD_ROM 0x00000002
#define FILE_DEVICE_CD_ROM_FILE_SYSTEM 0x00000003
#define FILE_DEVICE_CHANGER 0x00000030
#define FILE_DEVICE_CONTROLLER 0x00000004
#define FILE_DEVICE_DATALINK 0x00000005
#define FILE_DEVICE_DFS 0x00000006
#define FILE_DEVICE_DFS_FILE_SYSTEM 0x00000035
#define FILE_DEVICE_DFS_VOLUME 0x00000036
#define FILE_DEVICE_DISK 0x00000007
#define FILE_DEVICE_DISK_FILE_SYSTEM 0x00000008
#define FILE_DEVICE_DVD 0x00000033
#define FILE_DEVICE_FILE_SYSTEM 0x00000009
#define FILE_DEVICE_FIPS 0x0000003a
#define FILE_DEVICE_FULLSCREEN_VIDEO 0x00000034
#define FILE_DEVICE_INPORT_PORT 0x0000000a
#define FILE_DEVICE_KEYBOARD 0x0000000b
#define FILE_DEVICE_KS 0x0000002f
#define FILE_DEVICE_KSEC 0x00000039
#define FILE_DEVICE_MAILSLOT 0x0000000c
#define FILE_DEVICE_MASS_STORAGE 0x0000002d
#define FILE_DEVICE_MIDI_IN 0x0000000d
#define FILE_DEVICE_MIDI_OUT 0x0000000e
#define FILE_DEVICE_MODEM 0x0000002b
#define FILE_DEVICE_MOUSE 0x0000000f
#define FILE_DEVICE_MULTI_UNC_PROVIDER 0x00000010
#define FILE_DEVICE_NAMED_PIPE 0x00000011
#define FILE_DEVICE_NETWORK 0x00000012
#define FILE_DEVICE_NETWORK_BROWSER 0x00000013
#define FILE_DEVICE_NETWORK_FILE_SYSTEM 0x00000014
#define FILE_DEVICE_NETWORK_REDIRECTOR 0x00000028
#define FILE_DEVICE_NULL 0x00000015
#define FILE_DEVICE_PARALLEL_PORT 0x00000016
#define FILE_DEVICE_PHYSICAL_NETCARD 0x00000017
#define FILE_DEVICE_PRINTER 0x00000018
#define FILE_DEVICE_SCANNER 0x00000019
#define FILE_DEVICE_SCREEN 0x0000001c
#define FILE_DEVICE_SERENUM 0x00000037
#define FILE_DEVICE_SERIAL_MOUSE_PORT 0x0000001a
#define FILE_DEVICE_SERIAL_PORT 0x0000001b
#define FILE_DEVICE_SMARTCARD 0x00000031
#define FILE_DEVICE_SMB 0x0000002e
#define FILE_DEVICE_SOUND 0x0000001d
#define FILE_DEVICE_STREAMS 0x0000001e
#define FILE_DEVICE_TAPE 0x0000001f
#define FILE_DEVICE_TAPE_FILE_SYSTEM 0x00000020
#define FILE_DEVICE_TERMSRV 0x00000038
#define FILE_DEVICE_TRANSPORT 0x00000021
#define FILE_DEVICE_UNKNOWN 0x00000022
#define FILE_DEVICE_VDM 0x0000002c
#define FILE_DEVICE_VIDEO 0x00000023
#define FILE_DEVICE_VIRTUAL_DISK 0x00000024
#define FILE_DEVICE_WAVE_IN 0x00000025
#define FILE_DEVICE_WAVE_OUT 0x00000026

_DEVICE_OBJECT

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
typedef struct _DEVICE_OBJECT {
CSHORT Type;
USHORT Size;
LONG ReferenceCount;
struct _DRIVER_OBJECT *DriverObject;
struct _DEVICE_OBJECT *NextDevice;
struct _DEVICE_OBJECT *AttachedDevice;
struct _IRP *CurrentIrp;
PIO_TIMER Timer;
ULONG Flags;
ULONG Characteristics;
__volatile PVPB Vpb;
PVOID DeviceExtension;
DEVICE_TYPE DeviceType;
CCHAR StackSize;
union {
LIST_ENTRY ListEntry;
WAIT_CONTEXT_BLOCK Wcb;
} Queue;
ULONG AlignmentRequirement;
KDEVICE_QUEUE DeviceQueue;
KDPC Dpc;
ULONG ActiveThreadCount;
PSECURITY_DESCRIPTOR SecurityDescriptor;
KEVENT DeviceLock;
USHORT SectorSize;
USHORT Spare1;
struct _DEVOBJ_EXTENSION *DeviceObjectExtension;
PVOID Reserved;
} DEVICE_OBJECT, *PDEVICE_OBJECT;

_DRIVER_OBJECT

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
typedef struct _DRIVER_OBJECT {
CSHORT Type;
CSHORT Size;
PDEVICE_OBJECT DeviceObject;
ULONG Flags;
PVOID DriverStart;
ULONG DriverSize;
PVOID DriverSection;
PDRIVER_EXTENSION DriverExtension;
UNICODE_STRING DriverName;
PUNICODE_STRING HardwareDatabase;
PFAST_IO_DISPATCH FastIoDispatch;
PDRIVER_INITIALIZE DriverInit;
PDRIVER_STARTIO DriverStartIo;
PDRIVER_UNLOAD DriverUnload;
PDRIVER_DISPATCH MajorFunction[IRP_MJ_MAXIMUM_FUNCTION + 1];
} DRIVER_OBJECT, *PDRIVER_OBJECT;

程序调用

写入注册表

Windows学习001:CurrentControlSet和ControlSet001 - 知乎 (zhihu.com)

安装驱动程序的本质就是向注册表内写入对应的值

比如

1
2
3
4
5
6
7
8
9
10
11
12
13
RegCreateKeyExA(//创建指定的注册表项
HKEY_LOCAL_MACHINE,//也就是 注册表中"计算机\HKEY_LOCAL_MACHINE"这个路径
"System\\CurrentControlSet\\Services\\BrownProtector",//合起来就是注册表中实际项路径
0,
0i64,
1u,
0x20006u,
0i64,
&hKey,
0i64);
RegSetValueExA(hKey, "Type", 0, 4u, Data, 4u);//在键内创建一个键值对
RegSetValueExA(hKey, "Start", 0, 4u, Data, 4u);//在键内创建一个键值对
RegSetValueExA(hKey, "ImagePath", 0, 2u, (const BYTE *)v12, v1 + 1)//在键内创建一个键值对

RegCreateKeyExA

用于创建注册表项

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
LSTATUS RegCreateKeyExA(
[in] HKEY hKey,
/**
注册表项的句柄也算是注册表路径
HKEY_CLASSES_ROOT
HKEY_CURRENT_CONFIG
HKEY_CURRENT_USER
HKEY_LOCAL_MACHINE
HKEY_USERS
**/
[in] LPCSTR lpSubKey,//子路径
DWORD Reserved,
[in, optional] LPSTR lpClass,
[in] DWORD dwOptions,
[in] REGSAM samDesired,
[in, optional] const LPSECURITY_ATTRIBUTES lpSecurityAttributes,
[out] PHKEY phkResult,//输出的对应注册表项所存位置(实际上是个指针)
[out, optional] LPDWORD lpdwDisposition
);

RegSetValueExA

1
2
3
4
5
6
7
8
LSTATUS RegSetValueExA(
[in] HKEY hKey,//可以由 RegCreateKeyExA(创建注册表项)或者 RegOpenKeyEx(打开注册表项) 还有其他函数生成
[in, optional] LPCSTR lpValueName,//键
DWORD Reserved,//保留位,恒为0
[in] DWORD dwType,//数据类型
[in] const BYTE *lpData,//值
[in] DWORD cbData//lpdata大小,如果数据的类型为 REG_SZ、REG_EXPAND_SZ 或 REG_MULTI_SZ, 则 cbData 必须包含终止 null 字符的大小
);

驱动通信

CreateFileA

用于获取驱动的句柄

1
2
3
4
5
6
7
8
9
HANDLE CreateFileA(
[in] LPCSTR lpFileName,//驱动上来说,可以是device
[in] DWORD dwDesiredAccess,
[in] DWORD dwShareMode,
[in, optional] LPSECURITY_ATTRIBUTES lpSecurityAttributes,
[in] DWORD dwCreationDisposition,
[in] DWORD dwFlagsAndAttributes,
[in, optional] HANDLE hTemplateFile
);

DeviceIoControl

可以调用驱动api执行一些操作

1
2
3
4
5
6
7
8
9
10
BOOL DeviceIoControl(
[in] HANDLE hDevice,//设备句柄
[in] DWORD dwIoControlCode,//操作码
[in, optional] LPVOID lpInBuffer,
[in] DWORD nInBufferSize,
[out, optional] LPVOID lpOutBuffer,
[in] DWORD nOutBufferSize,
[out, optional] LPDWORD lpBytesReturned,
[in, out, optional] LPOVERLAPPED lpOverlapped
);
  • 标题: 驱动相关
  • 作者: runwu2204
  • 创建于 : 2024-03-30 00:02:58
  • 更新于 : 2024-04-02 20:35:14
  • 链接: https://runwu2204.github.io/2024/03/30/Re/windows/pe/驱动/驱动相关/
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。
评论