WindowsJul 5, 2023
Windows 驱动入门
这篇内容介绍了在Windows上开始使用驱动程序的一些基本知识。它包括了从用户模式(R3)到内核模式(R0)的API调用示例,以及如何创建和调试驱动程序。文章还提到了与驱动程序开发相关的一些概念,如IRP(I/O Request Packet)和不同的驱动程序开发框架(如WDM、KMDF、UMDF等)。最后,文章提到了一些准备工作和安装驱动程序的步骤,以及如何进行符号配置和源代码调试。
目录
前置知识#
R3 和 R0#

API 从 R3 到 R0#
text
#include <iostream>
#include <windows.h>
void testThread() {
while (true)
{
Sleep(1000);
}
}
HANDLE thread = 0;
int main()
{
thread = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)testThread, 0, 0, 0);
if (thread == 0) {
printf("CreateThread failed. GetLastError()=%dn", GetLastError());
system("pause");
return 0;
}
DebugBreak();
SuspendThread(thread);
system("pause");
}
text
# Child-SP RetAddr Call Site
00 ffff9f8473a21998 fffff80782aec1d8 nt!KiInsertQueueApc
01 ffff9f8473a219a0 fffff80782aec104 nt!KiSuspendThread+0x88
02 ffff9f8473a219f0 fffff80782edc197 nt!KeSuspendThread+0x78
03 ffff9f8473a21a40 fffff80782edc0f3 nt!PsSuspendThread+0x67
04 ffff9f8473a21aa0 fffff80782c0f3f5 nt!NtSuspendThread+0x93
05 ffff9f8473a21b00 00007ffa111907f4 nt!KiSystemServiceCopyEnd+0x25
06 000000fe5a72fbc8 00007ffa0e994a90 ntdll!NtSuspendThread+0x14
07 000000fe5a72fbd0 00007ff7b13d1a29 KERNELBASE!SuspendThread+0x10
08 000000fe5a72fc00 00007ff7b13d2459 SuspendDemo!main+0x89 [C:\Users\frendguo\source\repos\SuspendDemo\SuspendDemo\SuspendDemo.cpp @ 37]
09 000000fe5a72fd10 00007ff7b13d22fe SuspendDemo!invoke_main+0x39 [D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl @ 79]
0a 000000fe5a72fd60 00007ff7b13d21be SuspendDemo!__scrt_common_main_seh+0x12e [D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl @ 288]
0b 000000fe5a72fdd0 00007ff7b13d24ee SuspendDemo!__scrt_common_main+0xe [D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl @ 331]
0c 000000fe5a72fe00 00007ffa0f477604 SuspendDemo!mainCRTStartup+0xe [D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_main.cpp @ 17]
0d 000000fe5a72fe30 00007ffa111426a1 KERNEL32!BaseThreadInitThunk+0x14
0e 000000fe5a72fe60 0000000000000000 ntdll!RtlUserThreadStart+0x21Nt* 和 Zw* 的区别参考:
SSDT(System Service Descriptor Table)#
SSDT表中存放在一组服务函数, 通过该表找到该API在执行体 (Executive)(ntoskrnl.exe)中导出函数的位置,最终调用系统功能。

Windows IO 模型#
参考自:处理 IRP - Windows drivers | Microsoft Learn
内核模式驱动程序通过一个保护子系统对最终用户进行隐藏,该子系统实现了一个已经熟悉的编程接口,例如Windows或POSIX。设备仅对用户模式代码可见,包括受保护的子系统,但只作为由I/O管理器控制的具名文件对象。具体关系可以看下图:

下面官方有个图,来描述从 subsystem 中打开一个文件的过程:
来自:Example I/O Request - An Overview - Windows drivers | Microsoft Learn

具体到 IO 是怎么做的,可以看下面这个图:

可以看到,整个过程都是使用 IRP 来传输信息的。简化下:

模型中我们需要关注三个概念:
- I/O 请求使用
**IRP**从用户空间发送到驱动程序 - I/O 管理器(I/O manager)为所有内核模式驱动程序提供一致的接口。
- 此 I/O 管理器为每个已安装和加载的驱动程序创建一个驱动程序对象( driver object)。
IRP#

IRP 在驱动开发过程中不可避免的,除了 DriverEntry,还有我们的 R0 和 R3 通信,也是利用 IRP 来进行的。具体可以参考:
驱动类型#

具体分类可以看:
主要开发框架#
上个手#
0. 准备工作#
1. 写代码#
2. 调试#
-
安装驱动
-
Windbg 附加
-
符号配置、源配置
-
断点
3. 签名#
参考文档#
❝ Comments · 0
还没有评论。下面留下第一条吧。