简介

程序员、软件架构师、测试人员以及安全咨询师所面临的最大难题之一是,了解其应用程序部署到产品时的结果。即使具备对源代码的访问,也很难掌握执行过程中将发生的每个操作,这归咎于存在多种依赖项(例如,服务于代码或利用外部组件的多个组)。在帮助管理这种复杂性以及错误带来的潜在的负面影响方面,Microsoft AppVerifier 扮演着重要的角色。AppVerifier 有助于找到细小的编程错误、安全问题和用户帐户特权问题,这些错误和问题在典型的测试过程中是很难识别的。

什么是 Appverifier 校验器

AppVerifier 是一种旨在检测和帮助调试内存损坏、严重安全漏洞和受限用户帐户权限问题的工具。AppVerifier 通过监视应用程序与 Microsoft Windows 操作系统的交互并分析其对对象、注册表、文件系统和 Win32 API(包括堆、句柄和锁)的使用来帮助创建可靠和安全的应用程序。AppVerifier 还包括检查以预测应用程序在非管理环境中的执行情况。

在整个软件开发生命周期中使用时,AppVerifier 可以为开发工作带来成本效益,因为它有助于在问题更容易且更便宜地修复时及早发现问题。它还有助于检测可能未被注意到的错误,并确保最终应用程序可以在受限(例如,非管理员)环境中执行。

AppVerifier 有助于确定:

  1. 应用程序正确地使用 API 的时刻: 不安全的 Terminate Thread API。(在线程外终止一个线程,用于强制终止线程;这个函数的执行是异步的,无法保证调用之后会立即退出,如果使用 TerminateThread,那么在拥有线程的进程终止运行之前,系统不撤消该线程的堆栈,容易导致内存泄露) 正确使用线程本地存储(Thread Local Storage,TLS)API 正确使用虚拟空间操作(例如,VirtualAlloc 和 MapViewOfFile) 注:VirtualAlloc: 调用进程的虚地址空间,预定或者提交一部分页(申请内存空间) MapViewOfFile:将一个文件映射对象映射到当前应用程序的地址空间
  2. 应用程序是否使用结构化的异常处理隐藏访问冲突。
  3. 应用程序是否试图使用无效的句柄。
  4. 堆中是否有内存损坏或存在内存问题。
  5. 应用程序是否在资源不足的情况下用尽了内存。
  6. 是否正确使用了临界区。
  7. 运行在管理员环境中的应用程序在具有较低特权的环境中是否能良好运行。
  8. 当应用程序作为受限用户运行时是否会存在潜在的问题。
  9. 在线程的上下文中,是否在将来的函数调用中会存在未初始化的变量。

下载地址

https://developer.microsoft.com/zh-cn/windows/downloads/sdk-archive/

注意点:
只下载安装 win10SDK 中的 Application Verifier for Windows 即可
推荐使用版本:10.0.10240,太新的版本 有些老系统无法运行,如果是 win10 新系统,使用新版本即可

使用步骤

  1. 运行 AppVerifier,需要在 AppVerifier 中增加需要验证的应用程序,直接选择工程中输出的可执行文件,可以添加多个文件。

  2. 选择并保存将要验证可执行程序
    这是 AppVerf 会往注册表 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\ Windows NT\CurrentVersion\Image File Execution Options 下创建一个键,里面包含用户在 AppVerf 中设置的测试项,同时设置 GlobalFlag/PageHeapFlags 等键值对。配置需要验证的项目 AppVerifier tests 区选择需要进行测试的项目,并点击 save 保存设置(验证时使用,一般只需要勾选 basics 层)。

  3. 设置调试器
    需要设置调试器配合校验器测试
    在执行过程中,一旦程序触碰到了 AppVerf 划的警戒线 (如堆溢出/资源泄露等),就会触发断点异常,导致程序崩溃。可以通过 windbg 获取崩溃信息
    方法一 将 windbg 设置为默认调试器:使用后命令行 Windbg.exe -I
    方法二 为测试进程设置默认调试器:
    修改注册表:

    HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WindowsNT\CurrentVersion\Image File Execution Options   
    

    目标 exe (如 30clock.exe) 新建字符串类型项:

  4. 取消验证
    如果不删除验证程序,设置将一直保留;无论启动应用程序多少次,在启动时都会启用 AppVerifier 界面选中 exe 后右键 delete application

测试使用遇到的问题及解决方案

  1. 设置校验器后,无法启动程序
    遇到这种一般是测试过程中有其他 dll 有内存泄露、句柄等问题影响测试,可以先排除其他 dll 的影响,Memory 项右键属性 excludeDlls(AntiAdwa.dll 这个文件会有较多问题):

  2. 设置校验器后,程序启动卡顿
    以上问题大多是进程加载的 dll 比较多时(如 360tray.exe),最好排除其他不需要的 dll 的影响(不属于我们负责模块,这时需要开发协助),否则运行过慢,会影响测试;或者是使用 fullpageheap 了,开启的话需要高内存,这时只需要将其去下勾选即可

总结

校验器在使用中,可以帮助我们发现一些无感知的问题,从而增加产品的稳定性,降低风险;测试过程中一定要先设置校验器后再启动可执行程序,这样校验器才算是正常工作,注意还需要搭配 windbg 使用,这样在遇到问题的时候,可以第一时间发现问题;平时只使用常规校验项最后回归再使用 fullpageheap 不然会影响测试过程。

使用校验器过程中,若发现崩溃有时可能不是我们自身程序导致问题,这时需要与开发尽快确认问题原因,若不是则需要排除一些干扰的模块。

校验器与 API hook 原理机制是类似的,两者核心都是在进程发生异常的时候,捕获到异常进而分析其中问题;当然 API hook 也可以用于其他方面比如:监视指定线程的事件消息等


↙↙↙阅读原文可查看相关链接,并与作者交流