应用程序验证程序 - 概述
总结
应用程序验证程序 (AppVerifier) 是一款运行时验证工具,适用于非托管代码,可帮助查找一般应用程序测试技术难以识别的细微编程错误、安全问题和有限用户帐户特权问题。
概述
程序员、软件架构师、测试人员和安全顾问面临的最大挑战之一,就是要了解部署到生产中的应用程序的可变执行路径。 即使可以访问源代码,但由于存在各种依赖关系(例如,多个小组贡献代码或利用外部组件),也很难掌握执行过程中会发生的所有情况。 Microsoft AppVerifier 可以在帮助管理这种复杂性和错误的潜在副作用方面发挥有益的作用。 AppVerifier 可帮助查找编程错误、安全问题和用户账户权限问题,这些问题在一般测试过程中很难发现。
应用程序验证程序 (AppVerif.exe) 是 动态验证 工具,用于用户模式应用程序。 该工具可在应用程序运行时监控应用程序的操作,对应用程序进行各种压力和测试,并生成有关应用程序执行或设计中潜在错误的报告。
Application Verifier 可以检测任何非托管代码用户模式应用程序(包括用户模式驱动程序)中的错误。 它能发现在标准应用程序测试或驱动程序测试中难以发现的细微编程错误。
在软件开发的整个生命周期中使用 AppVerifier,可以为开发工作带来成本效益,因为它有助于在早期发现问题,而此时解决问题更容易,成本也更低。 它还有助于发现可能未被注意到的错误,并确保最终应用程序可在受限环境(如非管理员环境)中执行。
ARM64EC支持
应用程序验证程序不支持ARM64EC。
安装 AppVerifier
应用程序验证程序包含在 Windows 软件开发工具包 (SDK) 中。 要安装应用程序验证程序,请在安装 SDK 时选中该复选框。
您可以单独使用应用程序验证程序,也可以与用户模式调试器结合使用。 当前用户必须是计算机上管理员组的成员。
AppVerifier 检查什么?
AppVerifier 是一款用于检测和帮助调试内存损坏、关键安全漏洞和有限用户账户权限问题的工具。 AppVerifier 可监控应用程序与 Microsoft Windows 操作系统的交互,并分析其对对象、注册表、文件系统和 Win32 API(包括堆、句柄和锁)的使用情况,从而帮助创建可靠、安全的应用程序。 AppVerifier 还包括一些检查,以预测应用程序在非管理员环境下的性能。
AppVerifier 发现的问题
AppVerifier 可帮助确定
当应用程序正确使用应用程序接口时:
- 不安全的终止线程 API。
- 正确使用线程本地存储 (TLS) API。
- 正确使用虚拟空间操作(例如 VirtualAlloc、MapViewOfFile)。
- 应用程序是否使用结构化异常处理隐藏违规访问。
- 应用程序是否试图使用无效句柄。
- 堆中是否存在内存损坏或问题。
- 在资源不足的情况下,应用程序是否会耗尽内存。
- 是否正确使用关键部分。
- 在管理环境中运行的应用程序能否在权限较低的环境中运行良好。
- 当应用程序作为有限用户运行时,是否存在潜在问题。
- 线程上下文中的未来函数调用是否存在未初始化变量。
AppVerifier 测试
AppVerifier 由一组测试组成,称为 "验证层"。这些功能可为每个测试应用程序打开或关闭。 通过扩展测试区域内的验证层,可以显示具体的测试。 要打开应用程序的测试,请选择其旁边的复选框。 要打开整个验证层(如基础知识),请选择顶层的复选框。
AppVerifier 可以执行 13 种不同类型的测试。
基本信息 - 在运行应用程序验证程序时,至少应选择基础信息设置。 每项测试都将对会导致崩溃或其他负面情况的区域进行测试,这将对客户体验产生直接而重大的影响。 有关详情,请参阅应用程序验证程序 - 应用程序验证程序内的测试。
兼容性 - 兼容性验证层测试有助于识别可能与 Microsoft Windows 操作系统有问题的应用程序。 其中许多检查也可用于测试徽标要求。 有关详情,请参阅应用程序验证程序 - 应用程序验证程序内的测试。
Cuzz - 并发模糊(Cuzz)验证层可检测并发错误和数据竞赛条件。 Cuzz 通过在应用程序代码的关键点注入随机延迟来调整线程调度。 有关详情,请参阅应用程序验证程序 - 应用程序验证程序内的测试。
低资源模拟 - 低资源模拟试图模拟低资源环境,如内存不足。 该模拟将识别在低内存条件下出现的错误。 更多详情,请参阅应用程序验证程序 - 应用程序验证程序内的测试。
LuaPriv - 有限用户帐户特权预测程序 (LuaPriv) 测试既是预测性的,也是诊断性的,其作用是发现与使用管理特权运行应用程序有关的问题,以及该应用程序在使用较少特权(通常为普通用户)运行时是否也能正常工作。更多详情,请参阅应用程序验证程序 - 应用程序验证程序内的测试。
杂项 - 杂项包括各种测试,如针对采取不安全行动的危险应用程序接口的测试。 有关详情,请参阅应用程序验证程序 - 应用程序验证程序内的测试。
联网 - 联网测试查找 WinSock API 的不当使用。 例如,如果在成功调用 WSAStartup() 之前或平衡成功调用 WSACleanup() 之后调用了网络 API。 有关详情,请参阅应用程序验证程序 - 应用程序验证程序内的测试。
NTLM - 监控身份验证 API AcquireCredentialsHandle 和 InitializeSecurityContext 的使用,以检测 NTLM 协议的使用。 NTLM 是一种过时的身份验证协议,存在可能危及应用程序和操作系统安全的缺陷。 有关详情,请参阅应用程序验证程序 - 应用程序验证程序内的测试。
打印 - 打印验证程序可帮助查找应用程序调用打印子系统时可能产生的问题并排除故障。 打印验证工具面向打印子系统的两个层,即 PrintAPI 层和 PrintDriver 层。 有关详情,请参阅应用程序验证程序 - 应用程序验证程序内的测试。
Webservices - Windows Webservices API (WWSAPI) 验证层的作用是检查 WWSAPI 的正确使用,如调用的 WWSAPI 引用了无效的固有 WWSAPI 对象,或调用的 WWSAPI 引用了已在使用的单线程对象。 有关详情,请参阅应用程序验证程序 - 应用程序验证程序内的测试。
服务 - 服务测试,检查 Windows 服务的正确使用。 例如,服务是否正常启动和停止。 有关这些测试生成的停止代码异常的信息,请参阅应用程序验证程序 - 停止代码和定义。
Perf - Perf 测试检查影响系统性能和能耗的 API 的有效使用情况,如调用使用不正确等待时间的 Windows 函数。 有关这些测试生成的停止代码异常的信息,请参阅应用程序验证程序 - 停止代码和定义。
Hangs - Hangs 测试是否使用了导致系统无响应的 API,例如当 DllMain 线程正在等待另一个被阻塞的线程时。 有关这些测试生成的停止代码异常的信息,请参阅应用程序验证程序 - 停止代码和定义。
AppVerifier 如何工作?
AppVerifier 的工作原理是修改未托管的 DLL 方法表,以便在执行真正的函数之前执行所需的检查(这也称为 "函数挂钩")。 例如,Win32 API CreateFileA 方法的地址被替换为一个内部 AppVerifier 方法,该方法将触发一系列测试,如果测试结果呈阳性,将被记录下来。
启动新进程时,AppVerifier 方法表挂钩技术的使用由特定注册表键值中的条目控制。 如果注册表项存在,那么 AppVerifier DLL 将被加载到一个新创建的进程中,该进程将处理现有和随后加载的 DLL 中的方法表替换。 由于这些钩子是在加载 DLL 时创建的,因此无法在已经运行的进程中使用 AppVerifier。
AppVerifier 用户界面(UI)用于控制注册表密钥设置,并提供有关现有日志的信息。 在用户界面中设置应用程序和测试并点击 "保存 "按钮后,注册表设置就完成了。 然后需要重新启动应用程序,这将启动监控。 需要注意的是,这些设置将一直存在,直到应用程序从 AppVerifier 中删除。
一旦发现问题,核查员就会停止工作。 所提供的编号用于确定其确切性质和发生原因。
在软件开发生命周期中使用应用程序验证程序
您应在整个软件开发生命周期中使用应用程序验证程序。
需求阶段 - AppVerifier 应制定计划,并为其执行和跟进分配时间。
设计阶段 - 计划使用应用程序验证程序,并确定要测试的组件(模块、DLL 或 EXE)。
实施阶段 - 在开发中的不同组件的稳定版(从 Alpha 到 RTM)上运行应用程序验证程序(对组件进行单独和集体测试非常重要)。
验证阶段 - 测试人员应使用应用程序验证程序执行所有测试(包括手动和自动测试),因为这将是应用程序首次被推向极限,并将提交意想不到的行为和数据。 对于进行审计(黑盒和白盒)的安全顾问来说,AppVerifier 也是一个强大的工具,因为它可以快速列举真实(或潜在)的攻击/漏洞载体。
发布阶段 - 客户和安全顾问可在发布的二进制文件上使用 AppVerifier 识别潜在的安全漏洞。
支持和服务阶段 - 使用应用程序验证程序确保代码更改(如更新、服务包)不会引入回归。
章节主题
本部分包含以下主题。