f
frendguo.

Windows 驱动入门

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

目录
前置知识R3 和 R0API 从 R3 到 R0SSDT(System Service Descriptor Table)Windows IO 模型IRP驱动类型主要开发框架上个手0\. 准备工作1\. 写代码2\. 调试3\. 签名参考文档

前置知识#

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+0x21

Nt* 和 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 来传输信息的。简化下:

插图

模型中我们需要关注三个概念:

  1. I/O 请求使用 **IRP** 从用户空间发送到驱动程序
  2. I/O 管理器(I/O manager)为所有内核模式驱动程序提供一致的接口。
  3. 此 I/O 管理器为每个已安装和加载的驱动程序创建一个驱动程序对象( driver object)。

IRP#

插图

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

驱动类型#

插图

具体分类可以看:

主要开发框架#

上个手#

0. 准备工作#

1. 写代码#

2. 调试#

  • 安装驱动

  • Windbg 附加

  • 符号配置、源配置

  • 断点

3. 签名#

参考文档#

  1. 通过驱动接触win内核-编程技术-看雪-安全社区|安全招聘|kanxue.com
  2. https://bbs.kanxue.com/thread-275999.htm
  3. https://learn.microsoft.com/zh-cn/windows-hardware/drivers/kernel/handling-irps
── END ──
↑ Back to topSubscribe
← NEWER
深入理解 APC
OLDER →
线程挂起和恢复

还没有评论。下面留下第一条吧。

+ 留个评论
提交后由管理员审核 · 通常 24h 内显示
Jul 25Windows 权限相关概念解析4m →Mar 25Windows是如何区分互联网下载文件和本地文件的6m →Feb 25如何低成本的获取到应用卡顿情况3m →