Windows内核重拾:Windows驱动测试基础:工具、功能和示例(翻译/转载)

文章目录
  1. 1. 0x00 前言
  2. 2. 0x01 Windows驱动程序的定义及类型
    1. 2.1. Windows系统的驱动文件
    2. 2.2. 驱动类型
      1. 2.2.1. 用户模式驱动(User-Mode Drivers)
      2. 2.2.2. 内核模式驱动(Kernel-Mode Drivers)
    3. 2.3. 驱动程序与设备之间的关系
  3. 3. 0x02 Windows驱动程序测试主要内容
    1. 3.1. 不同操作系统
    2. 3.2. 更新
    3. 3.3. 硬件依赖性
  4. 4. 0x03 如何测试Windows驱动程序
    1. 4.1. 文件系统过滤器驱动程序
    2. 4.2. 虚拟存储驱动程序
    3. 4.3. USB设备驱动
  5. 5. 0x04 驱动程序测试和分析实用工具
    1. 5.1. 系统内置工具
      1. 5.1.1. Windows系统信息工具(msinfo32)
    2. 5.2. Windows Driver Kit实用工具
    3. 5.3. Windows设备控制台(devcon.exe)
    4. 5.4. PoolMon (poolmon.exe)
    5. 5.5. 驱动sys文件签名
  6. 6. 0x05 问题定位
  7. 7. 0x06 驱动测试报告模板
  8. 8. 0x07 结论

0x00 前言

本文旨在帮助你测试Windows驱动程序。因为有很多种不同的驱动程序,因此我们将介绍关于每种类型驱动程序的细节及各种驱动程序测试过程的不同点。我们也将涉及到一些驱动测试辅助工具和另一个重要的主题驱动数字签名。

0x01 Windows驱动程序的定义及类型

驱动程序是为物理或则虚拟设备提供接口的一种软件组件。驱动程序将来自用户程序和操作系统的high-level的请求翻译成物理/虚拟设备能够识别的low-level的指令。

Windows系统的驱动文件

Windows系统中,驱动文件以.sys扩展名文件存储,可能还会有以.inf或则.cat为后缀的辅助文件存在。
.inf文件
.inf文件是驱动程序安装文件,其中包含了设计驱动程序的设备的类型,驱动程序文件的位置以及所有依赖项。在驱动程序安装过程中,这些配置将从.inf文件写入到到注册表中,注册表作为驱动的配置文件。
.cat文件
.cat文件包含所有驱动程序文件的哈希值总和的列表。在Windows中,已安装的驱动程序通常保存在在%SystemRoot%\System32\drivers目录下,但也可以存储在任何其他位置。安装后,驱动程序已加载到系统中并可以使用。某些驱动程序类型在安装后需要重新启动。

驱动类型

根据执行模式的不同,驱动程序可以分为用户模式驱动和内核模式驱动。

用户模式驱动(User-Mode Drivers)

用户模式驱动程序在用户应用程序和其他操作系统组件(例如内核模式驱动程序)之间提供接口。打印机驱动程序就是是一种用户模式驱动程序。

内核模式驱动(Kernel-Mode Drivers)

内核模式驱动程序在内核特权模式下执行。不同内核模式驱动在执行期间通常会存在链式关系。每个驱动程序在链中的位置根据其作用不同。
一个用户模式程序查询设备的请求通常会经过多个驱动程序。经过的每一个驱动程序都将处理和过滤这个查询,根据Windows驱动程序术语这个包被称为IRP包(I/O请求包)。如果将驱动程序加载到链中的错误位置,则查询将被错误地处理,还有可能导致系统崩溃。
下面的图1表示磁盘的输入输出(I/O)查询的简化模型。用户应用程序创建查询以读取磁盘上的文件。该查询通过一系列驱动程序,每个驱动程序都会处理传入和传出的数据包。


图1 应用程序通过驱动查询的简化模型

在本文中,我们将重点介绍内核模式驱动程序。
内核模式驱动程序可以分为以下几种类型:

  • 即插即用设备驱动程序:这些驱动程序可以访问物理即插即用(PnP)设备并管理设备电源。
  • 非即插即用驱动程序:这些驱动程序增强了用户应用程序功能,并提供了对通过标准API调用不可用的内核模式功能的访问。这些驱动程序不适用于物理设备。
  • 文件系统驱动程序:这些驱动程序提供对文件系统的访问。它们将用于读取/记录文件的高级查询转换为用于磁盘驱动器的低级命令(在物理磁盘上读取/记录扇区)。
    Windows包含两种驱动开发模型:Windows驱动程序模型(WDM)、Windows驱动程序框架(WDF)。WDF由内核模式驱动程序框架(KMDF)和用户模式驱动程序框架(UMDF)组成的。WDM和WDF都简化了使驱动程序代码在Windows版本之间兼容的难度。
    WDM中包含以下驱动程序类型:

  • 总线类型驱动:这些驱动程序支持特定的PCI,SCSI,USB或其他端口,以控制新设备与总线的连接。

  • 功能驱动:这些驱动程序可确保特定设备的功能。它们通常支持读取/记录操作和设备电源管理。
  • 过滤驱动:这些驱动程序修改对设备的查询。它们可以位于驱动程序链中功能驱动程序的上方或下方。

驱动程序与设备之间的关系

每个内核模式驱动程序都与特定的设备一起使用,在Windows中以设备对象表示。这意味着通过驱动程序进行的I/O查询的最终目的地始终是物理或虚拟设备。这既适用于物理PnP设备的驱动程序,也适用于非PnP软件驱动程序。在测试驱动程序时,必须了解用户应用程序和设备之间存在多个驱动程序。在驱动程序执行链中每个驱动程序都可以影响对设备的最终查询结果。

0x02 Windows驱动程序测试主要内容

不管是Linux还是Windows,有一些特定的测试是驱动程序测试所必需的,并且与驱动程序类型无关。因此,在介绍测试不同类型驱动程序的细微差别之前,我们将首先考虑它们的共性。

不同操作系统

首先,您必须始终牢记,特定的驱动程序在不同的操作系统上的行为可能有所不同。此外,您需要考虑不同的内核版本,因为即使在同一操作系统中它们也可能有所不同。例如,Windows7和Windows7 sp1具有不同的内核。因此,您必须测试尽可能多的系统。值得一提的是,Microsoft目前还在继续支持的操作系统是从Win7/2008开始的。您还必须考虑到现在最流行的Windows版本是Windows 7和10。

更新

有必要测试驱动程序在特殊情况下的运行情况,例如关机,重新启动和重置。您还应该牢记系统的安全特性:防火墙,数据执行保护(DEP),用户帐户控制(UAC)和杀毒软件。操作系统更新也会影响驱动程序功能。因此将操作系统更新到最新版本测试至关重要。此外,您还需要测试驱动程序更新。

硬件依赖性

除了软件依赖性外,还有硬件依赖性。因此,您必须测试驱动程序在启用和禁用的页面文件、多处理器及多内核的运行情况。在测试驱动程序时,必须启用driver verifier,这将为驱动程序增加另外的测试压力。在测试过程中,请检查驱动程序安装和卸载,系统重置和休眠的正确性。

0x03 如何测试Windows驱动程序

测试驱动程序过程中始终会发生各种问题的,错误的操作甚至会导致严重的后果。因此,您应该在虚拟机中测试驱动程序直到稳定为止。

文件系统过滤器驱动程序

顾名思义,文件系统过滤驱动程序用于文件系统。因此,在测试此类驱动程序时,应使用NTFS,FAT32,exFAT和ReFS等文件系统进行测试。
为了正确测试Windows驱动程序,除了系统文件管理器Explorer之外,还应使用各种文件管理器,例如FAR或Windows Total Commander进行测试。此外,除了简单的操作(如复制,删除和重命名)外,不要忘记复杂的文件操作和文件系统变更。
复杂的文件系统变更包括:

  • 挂载/卸载新磁盘:
    • ISO image
    • 网络磁盘
    • 虚拟硬盘
    • U盘
  • 进行磁盘扇区配置变更(更改驱动器号或名称)
  • 在磁盘上执行的操作
    • 格式化分区
    • 压缩分区
    • 分区碎片整理
    • 磁盘坏道检查
    • 删除分区
    • 磁盘动态化
    • 在GPT / MBR中转换磁盘
    • 创建新分区
      您还必须检查:
  • 各种硬件配置(具有不同容量的SSD和HDD)
  • 停止和启动服务或安装/卸载应用程序时的驱动程序行为
  • 驱动程序如何与Windows工具与加密磁盘一起使用
  • 驱动程序与防病毒软件的兼容性,因为防病毒软件也是文件过滤类型驱动

虚拟存储驱动程序

在测试为虚拟存储创建的Windows驱动程序之前,您应该确保文件系统将是稳定的。对于虚拟存储驱动程序,应检查以下内容:

  • 驱动程序如何在以下情况下处理文件和文件夹
    • 打开操作
    • 创建操作
    • 编辑操作
    • 保存操作
    • 拷贝操作
    • 剪切操作
    • 重命名操作
    • 删除操作
  • 驱动程在文件和文件夹执行搜索操作如何工作的。
  • 驱动程序如何处理名称包含以下内容的文件
    • 字符过多
    • 数字
    • 空格
    • 特殊字符
    • 象形文字
    • 非Unicode
    • 西里尔字母
  • 驱动程序如何处理不同格式的文件:
    • 文本
    • 图像
    • 归档压缩文件
    • Office文件
  • 驱动程序如何处理具有各种属性的文件:
    • 只读属性
    • 隐藏属性
    • 系统属性
    • 归档属性
  • 驱动程序如何处理更改文件权限以及如何使用各种NTFS功能:
    • 压缩
    • 加密
  • 快捷方式(符号链接和硬链接)和隐藏副本是否正确。
  • 驱动程序如何处理不同大小的文件:
    • 非常小
    • 非常多非常小文件
  • 驱动程序如何处理包含大量子文件夹(超过五个)的文件夹。
  • 驱动程序如何处理冲突,例如使用目标中已存在的文件名复制文件或取消复制或删除。
  • 驱动程序如何处理保存从Internet或共享网络磁盘下载的文件。
  • 在正常情况和极端情况下都可以进行磁盘安装/卸载。例如,尝试在复制到存储时卸载,然后在重新引导系统后检查磁盘是否已成功安装。
  • 磁盘的读写速度。

USB设备驱动

对于USB驱动程序测试,您应该尝试覆盖尽可能多的USB设备。您可以从最受欢迎的设备开始,例如闪存驱动器,打印机,扫描仪,鼠标,键盘,便携式硬盘驱动器,智能手机和读卡器。但是,您还应该测试不太受欢迎的设备,例如蓝牙设备,以太网设备,USB集线器,麦克风和耳机,网络摄像头和CD-ROM驱动器。
您应该考虑各种USB接口:USB 1.0、2.0、3.0和3.1。此外,不要忘记拔出/插入设备,禁用安全和不安全的设备以及在设备管理器中删除设备。此外,检查设备驱动程序的安装和卸载。

0x04 驱动程序测试和分析实用工具

有许多用于测试Windows驱动程序的工具,这些工具使您可以监视系统中驱动程序的状态,验证其功能并执行测试。
内置的Windows工具足以获取有关驱动程序状态的基本信息(例如,是否已将其加载到系统中)。
内置Windows的工具:

  • Msinfo32
  • Driverquery
  • Sc Driver Verifier
    Sc Driver Verifier是一个系统内置工具,可让验证驱动程序功能。要深入分析测试驱动程序,您需要Windows驱动程序工具包(WDK)中提供的其他工具。

系统内置工具

Windows系统信息工具(msinfo32)

Msinfo32允许您获取系统中所有已安装驱动程序的列表,每个驱动程序的类型,其当前状态(已加载/未加载)以及启动模式(系统/手动)。
若要实用msinfo32,请使用Win + R调出“运行”对话框,然后启动msinfo32。在系统信息控制台的左侧栏中,选择以下选项卡:软件环境>系统驱动程序。




Msinfo32还可以查看和存储有关已注册驱动程序的信息。如果可以访问远程计算机的Windows Management Instrumentation(WMI),还可以查看远程计算机驱动程序列表,通过选项View > Remote Computer。
### Driverquery命令行实用程序
Driverquery提供的信息类似于msinfo32中的信息。可以使用driverquery命令通过cmd启动它:



还可以通过其他参数查询其他信息:
/V是用于详细输出的命令。它使您可以获得类似于msinfo32所示的驱动程序状态信息。
/SI提供有关已签名驱动程序的信息。
/S系统允许您获取有关远程系统上驱动程序的信息。

### 与服务控制管理器进行通信的sc命令
使用sc,命令可以查看驱动程序的状态以及启动或停止该驱动程序。要查看驱动程序列表,请运行以下命令:
sc query type= driver


Windows Driver Kit实用工具

Windows驱动程序工具包(WDK)提供了一系列用于驱动程序测试的工具。WDK与MS Visual Studio集成在一起,但也可以用作一组独立的实用程序。WDK包含一组称为“设备基础测试”的测试模块,以及其他特定的实用程序,使您可以管理设备和驱动程序,监视资源使用情况,并具有用于验证的实用程序等。
设备基础测试集包括以下测试:

  • 并行硬件和操作系统(CHAOS)测试
  • 覆盖率测试
  • CPU压力测试
  • 驱动安装测试
  • I/O测试
  • 渗透测试
  • 即插即用测试
  • 重启测试
  • 休眠测试
    为了执行测试,WDTF Simple I/O插件必须支持您的被测试设备。单击此链接以了解有关WDTF简单I/O插件的更多信息。
    设备基本测试以dll库的形式组织,并且位于%ProgramFiles%\Windows Kits\10\Testing\Tests\Additional Test目录下(Windows 10)。
    这些测试可以由TE.exe实用程序启动,该实用程序是Text Authoring和Execution Framework (TAEF)的一部分,必须与WDK一起安装。您可以在%ProgramFiles%\Windows Kits\10\Testing\Runtimes\TAEF目录中找到TE.exe。假设这是我们启动测试的示例:
    TE.exe Devfund_Device_IO.dll /P:”DQ=DriverBinaryNames=testdriver.sys”
    在此阶段,我们使用名为testdriver.sys的测试驱动程序作为参数启动设备I/O测试。设备基础测试和TAEF都非常适合驱动程序自动化测试。

Windows设备控制台(devcon.exe)

Windows设备控制台是一个命令行实用程序,它提供有关即插即用设备及其系统驱动程序的信息,并管理设备和特定设备类的筛选器驱动程序。使用devcon您可以安装、卸载、连接、断开和配置设备。Devcon允许您在搜索特定设备时设置模板。星号(*)可以替换查询中的一个或多个符号。
命令示例:

  • devcon.exe hwids * 显示所有设备的名称和ID的列表
  • devcon.exe classes 显示所有设备类别的列表
  • devcon.exe driverfiles * 显示所有系统设备的驱动程序文件列表
  • devcon.exe classfilter USBDevice upper 显示DiskDrive设备类的筛选器驱动程序
  • devcon.exe /r classfilter DiskDrive upper !OldFilter +NewFilter 替换DiskDrive设备类的筛选器驱动程序

PoolMon (poolmon.exe)

内存池监视器显示有关downloadable和nondownloadable核心内存分配的信息。该实用程序用于在测试时检测内存泄漏。




驱动程序的内存分配统计信息按标记而不是按驱动程序名称排序。应该使用ExAllocatePoolWithTag和ExAllocatePoolWithQuotaTag函数在驱动程序代码中设置此标记。如果未在代码中设置标签,则系统将设置”None”标签,这样的话定位驱动内存泄漏将会很困难。

### Windows Hardware Lab Kit
Windows Hardware Lab Kit(HLK)是用于测试基于Windows 10的设备的测试框架。要在Windows 7,Windows 8和Windows 8.1上进行Windows设备测试,您应该使用Windows HLK的前身Windows Hardware Certification Kit(HCK)。
在使用Windows HLK进行测试时,应使用由两个组件组成的环境:HLK测试服务器(controller)和测试系统(client)。HLK控制器管理一组测试,将它们与测试系统连接,并定义执行计划。该控制器允许您管理一组客户端计算机上的测试。在客户端系统中,设备和驱动程序被配置用于进一步的测试,并执行测试方案。可以通过以下步骤完成准备和测试过程:
- 1.将HLK c;ient安装在专用计算机上。
- 2.将agent程序安装在一台或多台测试计算机上。
- 3.创建一组以逻辑方式连接一个或多个计算机的测试计算机。
- 4.创建一个基于控制器的项目,该项目定义要测试的元素。
- 5.选择一个测试目标,例如测试机器的外部设备或软件组件,例如过滤器驱动程序。
- 6.选择并启动测试。您可以使用播放列表执行一组特定的场景。
- 7.查看并分析测试结果。
Windows HLK允许您测试多种类型的设备。您可以通过点击链接链接了解有关Windows HLK的更多信息。

### Driver Verifier

Driver Verifier是一个内置Windows实用程序,用于验证内核模式驱动程序。Driver Verifier使您能够检测可能损坏操作系统的驱动程序错误。使用WDK工具进行手动或自动测试时,Driver Verifier最有效。
Driver Verifier作为二进制Verifier.exe文件存储在%WinDir%\system32目录中。该实用程序可以以两种模式启动:通过命令行和Driver Verifier管理器。要启动命令行版本,请以管理员身份运行命令提示符,然后输入带有至少一个参数的verifier命令,例如help -verifier /?)。要打开驱动程序验证程序管理器,请运行不带参数的verifier。
让我们以Driver Verifier Manager为例查看驱动程序验证过程:
- 1.运行Driver Verifier Manager:Win + R>verifier
- 2.选择一组标准测试或创建自定义测试。管理器还可以显示和删除当前设置以及显示有关经过验证的驱动程序的信息:



- 3.选择一个或几个驱动程序进行测试。
- 4.重新启动计算机。将根据所选设置对驱动程序进行测试,直到将其从经过验证的驱动程序列表中删除。

#### Driver Verifier标准设置

下面,我们将介绍Windows 10 Driver Verifier程序的标准设置。在不同的Windows版本中,标准设置和补充设置的列表可能有所不同。
以下是Windows 10中Driver Verifier程序的标准选项:
- Special Pool
- Force IRQ Checking
- Pool Tracking
- I/O Verification
- Deadlock Detection
- DMA Verification
- Security Checks
- Miscellaneous Checks
- DDI Compliance Checking
下面我们看下每项设置的详细信息:
Special Pool
Driver Verifier的Special Pool选项可以分配出一块可以测试出驱动程序是否访问了被释放内存内存空间,这样就可以测试出驱动是否有内存访问问题。
Force IRQ Checking
在Windows中,如果启用了自旋锁选项,驱动程序将无法访问具有高IRQL的分页内存。Force IRQ Checking选项可以检测到此类问题。
Pool Tracking
Pool Tracking监视驱动程序的内存分配。 Driver Verifier检查为驱动程序分配的内存最终是否被释放。这有助于检测内存泄漏。
I/O Verification
I/O Verification选项可检测驱动程序对输入/输出的实用是否正确。在Windows 7及更高版本中,此选项还包含增强的I/O检查功能,该功能对以下请求执行压力测试:PnP IRP、电源IRP及WMI IRP。通过死锁检测,Driver Verifier可以监视驱动程序使用的同步对象,例如互斥锁和自旋锁,这就是可以检测到潜在的死锁。
DMA Verification
使用DMA Verification,Driver verification可以监视对Direct Memory的使用。DMA允许设备不经过CPU直接使用内存。
Security Checks
Driver Verifier的Security Checks选项可以检测出一些安全问题,如内核函数访问用户态内存地址或则不正确的参数使用。
Miscellaneous Checks
启用Miscellaneous Checks后,将对驱动程序进行测试,以检查可能导致驱动程序或系统崩溃的潜在错误,例如驱动释放了其他驱动正在使用的内存空间。
DDI Compliance Checking
在与操作系统的内核接口进行的通信(设备驱动程序接口)中检查驱动程序是否存在潜在错误。

为了有效地检测Driver Verifier中的错误,您应该遵循以下建议:
- 1.除非刻意这样,否则不要同时验证多个驱动程序。
- 2.下启用内存转储生成应对可能的系统崩溃情况(BSOD)。
- 3.如果需要启用调试模式并使用调试器通过网络或COM/USB端口连接到被测试系统。

### 驱动数字签名
在Windows XP,Windows Vista和Windows 7中,对安装驱动程序软件包的软件包签名没有严格要求。因此,您可以轻松安装没有签名的驱动程序。但是如果安装包未进行签名,会看到以下警告:


为了使驱动程序被识别为来自受信任的发布者,必须在Windows XP中使用Windows硬件质量实验室(WHQL)签名对驱动程序包进行签名。在Windows Vista和Windows 7中,必须使用受信任的根CA证书对驱动程序包进行签名。在Windows 8,Windows 8.1和Windows 10中,需要对驱动程序签名,因为没有它就无法安装驱动程序。过去需要使用SHA-1算法对证书进行加密。现在,SHA-1已过时,通常应该使用SHA-2算法应用于证书。
您可以通过以下链接了解有关SHA-2算法的更多信息。

驱动sys文件签名

在内核模式下运行驱动程序之前,Windows将检查驱动程序二进制.sys文件的数字签名。值得注意的是,Windows XP和Windows Vista 32位不需要数字驱动程序签名。Windows Vista 64位,Windows 7,Windows 8和Windows 8.1要求签名带有在其根目录中包含Microsoft Code Verification Root的证书,或者由内核信任的另一个证书。Windows 10版本1607及更高版本要求使用Windows Hardware Developer Center网站对驱动程序进行签名。
为了Windows驱动程序测试,您可以暂时禁用数字驱动程序签名检查。在Windows 10中,可以通过以下方式执行此操作:

  • 1.按住Shift键,然后在Windows主菜单中选择“重新启动”选项。
  • 2.选择Troubleshoot -> Advanced Options -> Startup Settings -> Restart
  • 3.在启动设置中,按F7键选择禁用驱动程序签名强制实施选项。



    要在启用了安全启动选项的Windows中测试驱动程序,必须确保驱动程序具有有效的签名。

0x05 问题定位

驱动程序中运行错误可能导致系统崩溃。因此,除了定义特定步骤外,本地化错误还意味着了解驱动程序是否造成了BSOD。为了确定这一点,您必须查看系统内存转储。这是在BSOD之后自动收集的,您可以在C:\Windows\Memory.dmp目录中找到它。要查看完整的内核转储,您应该告诉系统收集它。内核转储还包含有关磁盘上可用内存的必要信息。要获取此信息,您应该打开Advanced system settings > Startup,然后单击Settings。




检查是否启用了“完整内存转储”或“内核内存转储”选项。


在这些设置中,您可以更改内存转储的存储位置。
一旦有了完整的dmp,就应该对其进行分析。这是WinDbg有用的地方。使用此工具之前,您必须下载特定的Microsoft符号。您可以阅读本指南.aspx)以了解操作方法。
打开dmp文件并输入!analyze -v命令。注意堆栈,您将看到产生BSOD的原因。在某些情况下,您将无法从系统中获取转储文件,因为系统一直在崩溃。在这种情况下,您应该使用Windows高级启动选项。然后,您可以在几种特殊模式下运行系统。最简单,最可靠的一种是安全模式模式。在安全模式下,系统的一些操作将受到限制,您需要的只是获取C:\Windows文件夹中的dmp文件,这种操作安全模式使支持的。
您也可以尝试在系统故障时禁用自动重启功能,这可能有助于防止持续重启。如果系统崩溃,则应检查driver verifier是否启用。当开发人员尝试重现该错误时,此信息可能对他们非常有帮助。除了系统崩溃之外,您还可能面临其他问题,例如与功能或性能相关的问题。
要定位功能问题,您应该采取以下措施:
尝试在另一个环境中(在没有防病毒软件的其他操作系统中,在另一个文件系统上,使用实体计算机等)中重现问题。您也可以尝试其他条件,例如不同类型的文件和不同的文件大小。如果问题与您的USB设备有关,请检查其他类型的设备。如果网络是导致网络设备驱动程序错误的潜在原因,请检查各种网络设置(启动时间,带宽,启用或禁用防火墙)。当问题仅针对具有特定权限的用户出现时,请使用其他权限(管理员或标准)去定位问题。
如果问题与性能有关,则您的操作将取决于您要改善其性能的元素:

  • 如果问题出在网络设备驱动程序中,请模拟网络延迟或尝试在高速网络中重现这个问题。
  • 如果问题与文件操作有关,请使用不同数量的不同大小的文件进行验证。
  • 如果问题与USB摄像头有关,请使用其他应用层软件再进行测试验证。

0x06 驱动测试报告模板



0x07 结论

在本文中,我们描述了驱动程序的主要类型以及测试它们的方法和实用工具。Windows内核驱动程序测试与测试桌面应用程序有很大不同。如果驱动程序包含错误,通常会影响整个系统的稳定性,并最终导致BSOD。检测、定位和消除驱动程序错误,可以大大降低了最终用户系统行为不稳定的风险。

原文链接:https://www.apriorit.com/qa-blog/464-windows-driver-testing-basics