timzaak / blog

8 stars 1 forks source link

Windows 驱动开发入门 #106

Closed timzaak closed 9 months ago

timzaak commented 10 months ago

Write a Hello World Windows Driver (KMDF) Hello World 第一步。里面涉及相关依赖下载指引。 若是想用 Rust 开发,可以参考这个:windows-kernel-rs ,里面包含了常用的驱动编程思路和流程,Windows API 封装可使用官方提供的库: microsoft/windows-rs

开发大致流程

最核心的是:在 Windows-Driver-Samples 里扒相关源码,想办法跑起来,并在 demo 上更改。不建议自建项目,原因是环境依赖配置一大堆,对于接触 Visual Studio 不深的人来讲,简直要命。 另外由于闭源,你也无法从根本上去梳理整个架构,只能看文档怎么说,而往往文档总是存在滞后性和编排不合理性。 开发完毕后,还需要过EV代码签名(3800+)+ 微软认证,否则客户机器上无法使用。 参考: 通过证明对 Windows 10 及更高版本的驱动程序进行签名 - Windows drivers 避坑 | Windows驱动签名经验贴

Debug 流程

  1. 准备虚拟机/测试机 下载 windows.ios (不要用家庭版,Admin 权限在此版本下有限制),用虚拟机安装镜像,并设定固定IP,我是使用 NAT 的方式来固定的,桥接貌似每次重启会变更IP。 将宿主机 WDK 包中的 C:\Program Files (x86)\Windows Kits\10\Remote\x64 WDK Test Target Setup x64-x64_en-us.msi 复制到虚拟机,并安装。 在 Visual Studio 里的 Configure Devices 用IP添加设备,过程中会重启虚拟机,进入开发模式。 若是为了方便非驱动部分的调试,最好在虚拟机里安装完整的开发环境本地调试,目前 Windows 下的 C/Rust 的远程调试尚未找到好的方法论。
  2. Visual Studio Install Driver 项目->Driver Install->Deployment,选择 上一步骤配置的 Device,勾选 Hardware ID Driver Update,并输入INF文件里的 Standard.NT$ARCH$ -> hw-id 。若是通过软件安装驱动,则不需要如此。
  3. 拷贝文件到虚拟机 将宿主机的 DbgView.exe, TraceView.exe 拷贝过去用作调试工具,它们一般在 C:\Program Files (x86)\Windows Kits\10\Tools\$VERSION\x64下。 代码中若只用了 KdPrint 打印日志,就只需要 DbgView.exe。记得用管理员权限打开,并点击 Capture > kernel 启动内核捕获。 若是使用了 WPP Trace,则更麻烦些,通过虚拟机共享宿主机驱动编译生成的 .pdb 文件,TraceView.exe 在创建 LogSession 的时候需要用到,每次添加新的TraceEvents, 都需要重新创建LogSession, 否则会识别不了新创建的事件,最终发版后,可以通过从 .pdb 文件抽取 TMF 文件,来协助定位问题。
  4. 生产日志跟踪 用 tracepdb 生成TMF文件: cd C:\Program Files (x86)\Windows Kits\10\bin\10.0.22000.0\x64

    生成 TMF 文件(多个),$OUT_PATH 要是空目录。

    .\tracepdb.exe -f $PROJECT_PATH\x64\Debug\$DRIVER_NAMME.pdb -p $OUT_PATH 将 OUT_PATH 拷贝到虚拟机,用 TraceView.exe 创建 Log Session,此步骤会用到 Trace.h 里的 TraceControlGUID 和 OUT_PATH 内的 TMF 文件。 注意 TraceView.exe 将 logSession 保存到 workspace 再打开会出问题: Flags 和 Level 会丢失掉,无法跟踪日志。这就导致每次打开 TraceView.exe 都需要重新创建 Log Session,可通过挂起虚拟机来使虚拟机保持状态。另外,每次添加或更改 Trace 代码,都需要重新生成 TMF 文件。

驱动的安装与卸载

我一般使用Visual Studio Debug 来安装,然后 用设备管理器-> 查看->显示隐藏的设备,找到对应的虚拟设备,删除设备并勾选删除驱动来解决。

# 参考:https://learn.microsoft.com/zh-cn/windows-hardware/drivers/devtest/devcon-migration 
cd C:\DriverTest
# delete-driver 删除 驱动
pnputil.exe /delete-driver  $PROJECT.inf /uninstall
# add-driver 创建测试设备并安装驱动程序
pnputil.exe /add-driver  $PROJECT.inf /install

若有关联的 CommandLine App 用来调试驱动,需要将 App 以 Release 方式 Build,否则 Debug 模式编译出的应用在 虚拟机 上会加载动态dll,导致无法运行(最好在虚拟机内开发,方便debug)。

备注

  1. 用 WinObj.exe 可以查看当前设备树。Root 节点对应 GLOBAL?? 。
  2. 断点的使用体验很怪异,不知道是否是我使用的方法不对,目前先用日志来解决。

    Driver 与 Device 通过代码安装与卸载

    参考 Windows-samples setup/devcon 代码以及 将代码从 SetupApi 移植到 CfgMgr32 - Windows drivers。 完整的讲解参考:Device and Driver Installation - Windows drivers

    Driver 和 用户空间 通信方式

  3. COM(DLL) umdf V1 版本和老版本,umdf v2 已不再用
  4. File ioctl/read/write(device interface/symbolic)这个推荐使用
  5. share memory

    遇到的坑整理

  6. 网上的资料老旧,其书籍大都是Windows 2000 时代的,WDF很少,若不是做兼容性开发,意义基本不大。WDF 只支持Win10+, win7/XP 需要用 WDM 开发框架来做。
  7. Visual Studio 的开发工具配套问题,很多项目都是用 2015/2019 版本做的开发,导致 2022 年的版本有很多无法打开。若是可以,一个 Visual Studio 版本配套一个虚拟环境。
  8. Visual Studio 2022 不支持 x86架构、Windows 7以下 的驱动开发,所以目前最好用 Visual Studio 2019 来做驱动开发。
  9. Visual Studio 不支持 Windows Driver WPP Trace, 所以不要用其 Debug Driver。
  10. Windows 的开发工具兼容性做的好,导致很多可被替代的 API 被大量使用,你在阅读代码/文档的时候,根本不知道是否这个API已有更好的替代品。

    内存

  11. 内存可以写到硬盘(Paged)
  12. 内存对齐 Memory Management for Windows Drivers - Windows drivers

    Windows 开发额外资料

    DLL的生成、编写、调用总结_终不免俗的博客-CSDN博客_生成dll lib和dll文件的区别和联系_冯相文要加油呀的博客-CSDN博客_dll和lib INF 文件概述 - Windows drivers 不同的 IRP 处理方法 - 速查表 - Windows drivers 【Visual Studio 2019】创建 MFC 桌面程序 ( 安装 MFC 开发组件 | 创建 MFC 应用 | MFC 应用窗口编辑 | 为按钮添加点击事件 | 修改按钮文字 | 打开应用 ) 驱动开发之前,最好搞定最简单的MFC开发,好方便后续调试。 Youtube windows 开发讲解, 目前找到的最好入门资料,但也年代久远,OSR Driver Installer 等工具已不再维护。 Windows-driver-samples : windows 官方 example,写的比较完善,但注释和使用说明少,有很多 demo 最后一次更新都是几年前,需要老一些的 visual studio 搭配特定版本的 SDK 才能跑起来,README 里面关于代码编写流程可以参考。 Accessing device properties - Windows drivers

timzaak commented 10 months ago

kdnet 设置内核Debug 对网卡有限制。win11 目前VirtualBox、VMware 都无法成功,可能 Hyper-V 可以。

PS: 虚拟机 注意不要登录Microsoft 账号,貌似登录后,无法设置虚拟机为测试环境。 PS2: WDK 版本更新后,虚拟机里的 WDK 貌似会出现问题,即使重装 WDK Test Target Setup x64-x64_en-us.msi 也不行

Eco Kernel Debug 流程 这个流程我这边测试可过。 再将 C:\Program Files (x86)\Windows Kits\10\Remote\x64 下的 WDK Test Target Setup 在虚拟机上安装上,即可通过 Visual Studio 进行远程 DEBUG。 不过debug 效果不是很好,最后转向 TPP 这种疯狂打日志的方式来临时性解决

Show TPP Log in Windbg

目前未能找到合适的方案。