Abstract
如果推荐 Windows 驱动开发的入门书,我强烈推荐《Windows驱动开发技术详解》。但是由于成书的时间较早,该书中提到的很多工具和环境都已不可用或找不到,而本文搜集了大部分的工具,并在 win10X64 上安装开发环境,在 win7x86 上进行实验,趟过了不少实际编译和测试中遇到的坑。此外,本文也对相关章节的重点进行了总结,全文目录如下:
- 全书导读
- 开发和调试
- CH2 Windows操作驱动的基本概念
- CH3 驱动编译环境配置、安装和调试
- CH4 驱动程序的基本结构
- CH5 Windows内存管理
- CH6 Windows内核函数
- CH7 派遣函数
- CH8 驱动程序的同步处理
- CH9 IRP的同步
- CH10 定时器
- CH11 驱动程序调驱动程序
- CH12 分层驱动程序
- CH13 即插即用
- CH21 再论IRP
- CH22 过滤驱动程序
- CH23 高级调试技巧
全书导读
《Windows驱动开发技术详解》全书由浅入深分为四个部分:入门篇、进阶篇、实用篇和提高篇,可以参考 目录结构。
本人之前从事 Windows PCIe 设备驱动开发,目前从事网络安全方面的工作,本文是我利用春节假期复习《Windows驱动开发技术详解》所写。由于现在的工作不涉及具体的设备驱动,所以书中“实用篇”被我跳过了,从事安全方面开发的人员只需要掌握驱动模型即可。
全书阅读的建议是:基础篇快速阅读,把每个实验做一遍即可。进阶篇认真阅读和实验,而提高篇实际上就是前面知识的总结,看以当作复习和综合练习。
此外,在我的资源里有相关的全书源码,也有我自己实验的 DDK build 版源码。鉴于原书代码大部分是 VC 版,而且使用的是老版本的VC ,我在实验时,全部将其驱动代码改为了 DDK build 版本。应用程序部分则采用 VS2017 新建 win32 console 工程进行编译。
开发和调试
驱动开发工具
《Windows驱动开发技术详解》和《Windows内核安全编程》配套的 Driver Build 工具都是 WDK7600。它可以从 MSDN 上下载,也可以直接从如下链接下载,选择“Full Development Environment” ,默认路径安装即可(无须设置环境变量)。
驱动日志工具
最经典的驱动日志工具是 sysinternals - DbgView.exe,通过 C 风格的 KdPrint() 函数输出日志。需要注意的是:KdPrint() 的日志只在 Checked Build 版本中才可见,在 Free Build 版本不可见。
此外,Microsoft 也提供了一套 Driver 日志机制—— WPP + TraceView.exe,适合有 PDB 文件的日志分析。
驱动运行状态观察工具
Procexp.exe 可以观察驱动的运行状态,此外,还有 livekd.exe 和 kd.exe。
DriverView.exe 用于观察系统已安装的全部驱动程序,也可以使用 CMD - systeminfo 命令查看驱动信息。
驱动安装工具
KmdManager.exe 是驱动加载和测试工具,Link。如下图所示,它提供了驱动的注册、启动服务(net start ***)和发送相关 IOControl 的功能。
srvinstw.exe 是《Windows内核安全编程》推荐的一款驱动加载工具,并配有详细的操作步骤。
需要注意的是:KmdManager.exe 和 srvinstw.exe 都需要使用“管理员权限”运行。
除了 Driver Studio,Windows 驱动安装首选 devcon.exe。它是附在 Windows WDK 中的一个工具。
WinDbg
驱动相关的操作系统知识
其中,native api 对应的 PE 是 ntdll.dll,其 API 一般都以 Nt开头;而“系统服务函数”对应的 PE 是 ntosknrl.exe,其 API 一般都以 Zw 开头。此外,可以通过 Dependency walker.exe 查看其导出函数。
驱动程序的编译和调试
这一章主要介绍 Windows 驱动程序的开发环境搭建,驱动程序安装和驱动程序调试,主要参考《Windows驱动开发技术详解》的第三章和《Windows内核安全编程》第一章。其中,examples 用的是前者的,而开发环境和工具都使用的是后者的。
HelloDDK
HelloDDK 是一个 NT驱动,也就是说,它是一个非 PnP 驱动,仅以系统服务的形式存在,并不与设备相关。
- 安装好 WDK7600后,启动 “Windows Driver Kits - x86 Checked Build Environment” 命令窗口,导航到源码目录。
- 输入 “build” 指令,生成 sys 文件。
- 在目标机器运行 srvinstw.exe ,安装该服务驱动。
- cmd - net start/stop helloddk ,开启/停止该服务。
需要注意:
- 安装该服务后,可以在如下注册表中看到
HKLM\SYSTEM\CurrentControlSet\services\HelloDDK
从《Windows驱动开发技术详解》第三章可知,服务安装的过程,实际上就是写注册表的过程。
2. 用 DbgView.exe 观察的时候,需要“管理员权限运行”和开启“Capture Kernel + Enable Verbose Kernel Output”。
3. 需要重启才能在 DeviceManager 中看到该新安装的“非即插即用设备”。
4.
LoadNTDriver
LoadNTDriver 程序演示了如何调用 SCM 加载/卸载 NT 驱动程序,该程序源码(main.cpp)可疑放到一个 VS2017 的 win32 console 应用程序中 build,仅需修改以下几处:
- Unicode 改为 “多字节字符集”
- LoadNTDriver 和 UnloadNTDriver 形成增加 const 修饰
- getch -> _getch
- 可以将运行时改为 MT
HelloWDM
SubKey
HelloWDM 是一个 PnP 驱动,它注册的时候会创建三个子健:
Hardware子健
HKLM\SYSTEM\CurrentControlSet\Enum
Class子健
HKLM\SYSTEM\CurrentControlSet\Control\Class
service子健
HKLM\SYSTEM\CurrentControlSet\services\
INF
与 NT 驱动不同,WDM 驱动的注册表信息和设备信息都是在 INF 文件中定义的。《Windows驱动开发技术详解》CH1&CH3 都有对 INF 文件很详细的介绍。
安装HelloWDM
通过 DeviceMgr - root 选择“安装过时硬件” - 手动安装 - 从磁盘安装。