使用静态驱动程序验证程序查找 Windows 驱动程序中的缺陷

静态驱动程序验证器 (SDV) 使用一组接口规则和操作系统模型来确定驱动程序是否与 Windows 操作系统正确交互。 SDV 在驱动程序代码中查找一些缺陷,这些缺陷可能指向驱动程序中的潜在 bug。

SDV 可以分析符合以下驱动程序模型之一的内核模式驱动程序: WDM、KMDF、NDIS 或 Storport。 有关详细信息,请参阅 支持的驱动程序确定 Static driver Verifier 是否支持驱动程序或库。 此外,SDV 还 (严格限制的规则集提供有限的支持,该规则集中侧重于对不遵循以上驱动程序模型的驱动程序) 取消引用的常规错误。

准备源代码

使用以下步骤准备要分析的代码。

  1. 使用函数角色类型声明驱动程序提供的函数

    SDV 要求通过使用函数角色类型声明来声明函数。 例如,必须使用 DRIVER_INITIALIZE 函数角色类型声明 DriverEntry 例程:

    DRIVER_INITIALIZE DriverEntry;
    

    在声明后,按如下所示实现 (或定义) 回调例程:

    /
    // Driver initialization routine
    //
    NTSTATUS
      DriverEntry(
        _In_ struct _DRIVER_OBJECT  *DriverObject,
        _In_ PUNICODE_STRING  RegistryPath
        )
      {
          // Function body
      }
    

    每个受支持的驱动程序模型都具有一组用于驱动程序回调函数和调度例程的函数角色类型。 这些函数角色类型在 WDK 标头文件中声明。 例如,下面是 DRIVER_INITIALIZE 角色类型的函数原型,因为它显示在 Wdm 中。

    /
    // Define driver initialization routine type.
    //
    _Function_class_(DRIVER_INITIALIZE)
    _IRQL_requires_same_
    typedef
    NTSTATUS
    DRIVER_INITIALIZE (
        _In_ struct _DRIVER_OBJECT *DriverObject,
        _In_ PUNICODE_STRING RegistryPath
        );
    
    typedef DRIVER_INITIALIZE *PDRIVER_INITIALIZE;
    

    由于已在 WDK 标头文件中定义了函数角色类型,因此只需将回调函数声明为该类型。 在这种情况下,将 DriverEntry 类型声明为 DRIVER_INITIALIZE类型。 有关驱动程序模型的函数角色类型的完整列表,请参阅 使用函数角色类型声明

  2. 为 c/c + + 运行 Code Analysis

    为了帮助您确定是否已准备好源代码,请在 Visual Studio 中运行Code Analysis 工具。 Code Analysis 工具检查是否存在 SDV 所需的函数角色类型声明。 Code Analysis 工具可帮助确定任何可能已丢失的函数声明,如果函数定义的参数与函数角色类型中的参数不匹配,则会发出警告。

    • 在 Visual Studio 中打开驱动程序项目。
    • 在 "生成" 菜单中,单击 "在解决方案上运行 Code Analysis"

    结果将显示在 " Code Analysis " 窗口中。 修复任何可能丢失的函数声明。 你还可以配置 Code Analysis 工具,使其在每次生成解决方案时运行。

    下表显示 Code Analysis 工具可能在你的驱动程序代码中发现的一些警告。 若要运行静态驱动程序验证程序,你的驱动程序需要没有这些缺陷。

    C/c + + 代码分析警告 说明
    C28101 驱动程序模块已推断出当前函数是 <function-type> 函数
    C28022 此函数上的函数类与用于定义它的 typedef 的函数类不匹配。
    C28023 要分配或传递的函数应具有针对至少一个类的 _Function_class_ 批注
    C28024 要分配到的函数指针是用函数类批注的,它未包含在函数类列表中。
    C28169 调度函数 < 函数 > 没有任何 _Dispatch_type_ 批注
    C28208 函数签名与函数声明不匹配

运行静态驱动程序验证程序

  1. 在 Visual Studio 中 () 文件中打开驱动程序项目。 在 " 驱动程序 " 菜单中,单击 " 启动静态驱动程序验证程序 ..."。

    这会打开静态驱动程序验证程序应用程序,你可以在其中控制、配置和计划静态驱动程序验证程序执行分析的时间。

  2. 如果驱动程序包含库,请单击 " " 选项卡,然后单击 " 添加库 " 以添加库。

    浏览到库源代码的目录,并选择项目文件 ( ".Vcxproj") 。 添加驱动程序包含的所有库。 在 SDV 分析驱动程序之前,必须添加这些库。 当你开始分析你的驱动程序时,SDV 还会分析尚未处理的库。 库处理完毕后,将存储在全局 SDV 缓存中。 有关详细信息,请参阅 静态驱动程序验证程序中的库处理

  3. 检查静态驱动程序验证程序的配置设置。 单击“配置”选项卡。

    Project 配置Project 配置显示在 Visual Studio 中选择的配置和平台设置。

    资源 在大多数情况下,您可以使用默认设置。 如果 SDV 报告 "超时"、"放弃" 或 "Spaceout",则可以尝试调整这些设置。 有关详细信息,请参阅用于排查静态驱动程序验证程序问题的推荐

    计划 选择开始验证的开始时间。 默认设置是在单击选项卡上的 "启动" 后立即开始分析。静态分析可能需要较长时间才能运行,具体取决于驱动程序的大小及其复杂性。 你可能希望将分析计划为在最方便的时候开始分析;例如,在一天结束时。

    备注

    ] 确保检查计算机的电源管理计划,以确保在分析期间计算机不会进入睡眠状态。

  4. 单击 " 规则 " 选项卡,选择在启动分析时要验证的驱动程序 API 使用规则。

    静态驱动程序验证程序检测到正在分析的驱动程序类型 (WDF、WDM、NDIS 或 Storport) 并为驱动程序类型选择默认的规则集。 如果这是你第一次在你的驱动程序上运行 SDV,则应该运行默认规则集。

    有关规则的信息,请参阅 DDI 合规性规则

  5. 开始静态分析。 单击 " " 选项卡,然后单击 " 启动"。 单击 " 启动" 时,将显示一条消息,告知你计划了静态分析并且分析可能需要较长时间才能运行。 单击 “确定” 继续。 分析从你计划的时间开始。

查看并分析结果

在静态分析过程中,SDV 将报告分析的状态。 分析完成后,SDV 会报告结果和统计信息。 如果驱动程序无法满足 API 使用规则,则结果将报告为缺陷。

如果遇到任何问题,SDV 将在 " 警告 " 和 " 错误 " 页上显示这些问题。 " 驱动程序属性 " 页显示某些驱动程序属性的测试结果。 驱动程序属性测试用于标识驱动程序功能,以进一步限定分析。 您可以使用 驱动程序属性 结果来确认您的驱动程序所需的属性和支持的功能。

若要查看 静态驱动程序验证程序报告中的特定缺陷,请在 结果 窗格中单击 "缺陷"。 这会打开 跟踪查看器,其中显示规则冲突的代码路径跟踪。 有关详细信息,请参阅 解释静态驱动程序验证程序结果

备注

静态驱动程序验证程序保留分析的结果和设置。 若要清除结果,请单击 " 清除"。

静态驱动程序验证程序结果疑难解答

如果 SDV 报告未找到缺陷,请检查 选项卡以确保检测到入口点。 如果驱动程序没有使用函数角色类型声明函数,则 SDV 将无法分析和查找驱动程序代码中的缺陷。 有关详细信息,请参阅 使用函数角色类型声明

如果 SDV 报告超时或无法返回有用的结果,则可能需要更改几个 SDV 配置选项。 有关如何对 SDV 进行故障排除的详细信息,请参阅用于排查静态驱动程序验证程序问题的推荐

确定静态驱动程序验证程序是否支持你的驱动程序或库

使用函数角色类型声明

静态驱动程序验证程序规则

Code Analysis 工具