应用验证程序测试设置详解
1. 内存测试设置
内存测试设置可捕获众多与内存操作相关的编程错误,如向内存 API 传递无效参数、对象初始化失败以及模块卸载问题等。默认情况下,所有与内存相关的停止代码触发时都会使调试器中断。以下是详细的停止代码及其说明:
| 停止代码 | 测试 | 描述 |
| — | — | — |
| 00000600 | VirtualFree 或 Dll 卸载 | 当应用验证程序检测到带有无效地址的 VirtualFree 调用或带有无效起始地址的 DLL 卸载时触发 |
| 00000601 | VirtualAlloc | 当检测到带有无效起始地址或分配大小的 VirtualAlloc 调用时触发 |
| 00000602 | MapViewOfFile | 当检测到带有无效基地址或映射大小的 MapViewOfFile 调用时触发 |
| 00000603 | IsBadXXXPtr | 当检测到带有无效地址的 IsBadXXXPtr 调用时触发 |
| 00000604 | IsBadXXXPtr | 当检测到使用已释放内存位置的 IsBadXXXPtr 调用时触发 |
| 00000605 | IsBadXXXPtr | 当检测到使用包含保护页的内存地址的 IsBadXXXPtr 调用时触发,若地址指向栈,问题可能更严重 |
| 00000606 | IsBadXXXPtr | 当检测到使用空地址的 IsBadXXXPtr 调用时触发 |
| 00000607 | IsBadXXXPtr | 当检测到带有无效地址或内存缓冲区大小的 IsBadXXXPtr 调用时触发 |
| 00000608 | Dll 卸载 | 当以无效起始地址卸载 DLL 时触发 |
| 00000609 | VirtualFree | 当对当前线程栈的一部分地址使用 VirtualFree 调用时触发 |
| 0000060A | VirtualFree | 当以错误的 FreeType 参数调用 VirtualFree 时触发 |
| 0000060B | VirtualFree | 当对已释放的地址调用 VirtualFree 时触发 |
| 0000060C | VirtualFree | 当以 MEM_RELEASE 调用 VirtualFree 且大小参数大于 0 时触发 |
| 0000060D | DllMain 异常 | 当 DllMain 实现引发异常时触发 |
| 0000060E | 线程异常 | 当线程引发异常时触发 |
| 0000060F | IsBadXXXPtr | 当调用 IsBadXXXPtr 导致抛出异常时触发 |
| 00000610 | VirtualFree | 当以 MEM_RESET 和 null 作为第一个参数调用 VirtualFree 时触发 |
| 00000612 | HeapFree | 当使用当前线程栈的一部分指针调用 HeapFree 时触发 |
| 00000613 | UnmapViewOfFile | 当对当前线程栈的一部分内存块调用 UnmapViewOfFile 时触发 |
| 00000614 | 错误地址 | 当向某些 API 传递无效地址时触发,如向 RtlInitializeResource 传递 null |
| 00000615 | 错误地址 | 当向某些 API 传递无效地址时触发,如向 EnterCriticalSection 传递 null |
| 00000616 | 非可执行代码 | 当应用程序尝试从不可执行的内存地址运行代码时触发 |
| 00000617 | 缓冲区初始化失败 | 当在初始化传递给 Win32 或 CRT API 的输出参数时引发异常,通常表示关联的大小参数不正确 |
| 00000618 | HeapSize | 当使用已释放内存块的地址调用 HeapSize API 时触发 |
| 00000619 | VirtualFree | 当以无效基地址调用 VirtualFree 时触发,无效指指定的基地址与相应的 VirtualAlloc 或 VirtualAllocEx API 返回的基地址不同 |
| 0000061A | UnmapViewOfFile | 当以无效基地址调用 UnmapViewOfFile 时触发,无效指指定的基地址与相应的 MapViewOfFile 或 MapViewOfFileEx API 返回的基地址不同 |
| 0000061B | 线程池线程异常 | 当线程池线程的回调函数引发异常时触发 |
| 0000061C | 非可执行代码 | 当应用程序尝试从不可执行的内存地址运行代码时触发 |
| 0000061D | 可执行堆 | 当应用程序尝试创建可执行堆时触发 |
| 0000061E | 可执行内存 | 当应用程序尝试分配可执行内存时触发 |
内存测试设置有一个可调整的属性
ExecWritePage
,可控制是否检查应用程序是否正在创建或分配可执行且可写的内存。
2. 线程池测试设置
原生 Windows 线程池是应用程序需要多个线程时强大且方便的组件。使用线程池时,操作系统会决定何时以及如何创建线程,但也带来了很多责任。不当使用线程池会导致难以追踪的错误,例如更改线程状态后未重置就将线程返回线程池。该测试设置可捕获这些问题并通知开发者。以下是相关的停止代码及其说明:
| 停止代码 | 测试 | 描述 |
| — | — | — |
| 00000700 | 更改线程优先级 | 如果应用程序更改了线程的优先级,且在将线程返回线程池之前未重置,此停止代码将触发 |
| 00000701 | 更改线程亲和性 | 如果应用程序更改了线程的亲和性,且在将线程返回线程池之前未重置,此停止代码将触发 |
| 00000702 | 未处理的消息 | 如果线程在返回线程池之前有任何未处理的消息,此停止代码将触发 |
| 00000703 | 活动窗口 | 如果线程在返回线程池时有任何活动的窗口,此停止代码将触发 |
| 00000704 | 线程退出或终止 | 如果对线程池线程调用 ExitThread 或 TerminateThread,此停止代码将触发 |
| 00000705 | 模拟 | 如果线程池线程模拟了另一个用户,但在将线程返回线程池之前未恢复模拟,此停止代码将触发 |
| 00000706 | 专用线程 | 在某些情况下,某些 API 需要在持久或专用线程上调用(如 RegNotifyChangeKeyValue API),除非从线程池请求了专用线程,否则此停止代码将触发 |
| 00000707 | 事务句柄 | 如果应用程序在将线程返回线程池之前忘记重置事务句柄,此停止代码将触发 |
| 00000708 | COM 初始化 | 在线程上初始化 COM 时,必须在线程退出之前正确取消初始化。如果 COM 初始化和取消初始化的调用不平衡,此停止代码将触发 |
线程池测试设置还有一个关联属性
AsyncCheck
,可使验证程序检查需要持久线程的异步调用。将此设置设为 1 可开启,默认值为 0(关闭)。
3. TLS 测试设置
线程本地存储(TLS)是分配线程特定本地数据的常用机制。应用程序使用 TLS 系列 API 分配 TLS 数据,此测试设置可确保这些 API 的正确使用,遇到无效使用时会停止执行。以下是相关的停止代码及其说明:
| 停止代码 | 测试 | 描述 |
| — | — | — |
| 00000350 | TlsIndex 泄漏 | 如果分配了 TLS 索引的 DLL 在卸载时未释放该索引,此停止代码将触发以避免 TLS 索引泄漏 |
| 00000351 | 损坏的 TLS 状态 | 如果用于存储 TLS 槽的数据结构损坏,此停止代码将触发,很可能是随机内存损坏导致 |
| 00000352 | 使用无效的 TLS 索引 | 如果应用程序使用了被认为无效的 TLS 索引,此停止代码将触发,常见原因是使用了已释放的 TLS 索引 |
4. 文件路径测试设置
使用系统文件路径(如获取 Windows 目录或系统目录)的应用程序可能会因使用错误路径而出现问题。此测试设置可确保通过 Win32 API 获取的系统路径正确。默认情况下,所有与文件路径相关的停止代码触发时不会使调试器中断,而是将停止代码和调用栈记录到日志文件中。以下是相关的停止代码及其说明:
| 停止代码 | 测试 | 描述 |
| — | — | — |
| 00002400 | 通用程序路径 | 如果应用程序使用了未通过正确 API 获取的通用程序目录路径,此停止代码将触发 |
| 00002401 | 通用开始菜单目录路径 | 如果应用程序使用了未通过正确 API 获取的通用开始菜单目录路径,此停止代码将触发 |
| 00002402 | 程序目录路径 | 如果应用程序使用了未通过正确 API 获取的程序目录路径,此停止代码将触发 |
| 00002404 | 开始菜单目录路径 | 如果应用程序使用了未通过正确 API 获取的开始菜单目录路径,此停止代码将触发 |
| 00002405 | Windows 临时路径 | 如果应用程序使用了未通过正确 API 获取的 Windows 临时路径,此停止代码将触发 |
| 00002406 | Windows 目录路径 | 如果应用程序使用了未通过正确 API 获取的 Windows 目录路径,此停止代码将触发 |
| 00002407 | 系统 Windows 目录路径 | 如果应用程序使用了未通过正确 API 获取的系统 Windows 目录路径,此停止代码将触发 |
| 00002408 | 系统目录路径 | 如果应用程序使用了未通过正确 API 获取的系统目录路径,此停止代码将触发 |
| 0000240A | 我的文档目录路径 | 如果应用程序使用了未通过正确 API 获取的我的文档目录路径,此停止代码将触发 |
5. HighVersionLie 测试设置
依赖硬编码 Windows 版本号是导致应用程序崩溃的常见编程错误。为避免这种情况,此测试设置允许开发者针对“未来”版本的 Windows 测试代码。应用验证程序会拦截对 GetVersion 和 GetVersionEx API 的调用,并返回一个默认情况下高于最新 Windows 版本的版本号。例如,在 Windows XP Professional Service Pack 2 上运行调用 GetVersionEx 的简单测试应用程序:
Local var @ 0x7fea4 Type _OSVERSIONINFOEXA
+0x000 dwOSVersionInfoSize : 0x9c
+0x004 dwMajorVersion : 5
+0x008 dwMinorVersion : 1
+0x00c dwBuildNumber : 0xa28
+0x010 dwPlatformId : 2
+0x014 szCSDVersion : [128] “Service Pack 2”
+0x094 wServicePackMajor : 2
+0x096 wServicePackMinor : 0
+0x098 wSuiteMask : 0x300
+0x09a wProductType : 0x1 ‘’
+0x09b wReserved : 0 ‘’
开启 HighVersionLie 测试后再次运行应用程序:
Local var @ 0x7fea4 Type _OSVERSIONINFOEXA
+0x000 dwOSVersionInfoSize : 0x9c
+0x004 dwMajorVersion : 7
+0x008 dwMinorVersion : 3
+0x00c dwBuildNumber : 0xe10
+0x010 dwPlatformId : 2
+0x014 szCSDVersion : [128] “”
+0x094 wServicePackMajor : 2
+0x096 wServicePackMinor : 0
+0x098 wSuiteMask : 0x300
+0x09a wProductType : 0x1 ‘’
+0x09b wReserved : 0 ‘’
此时,主版本和次版本是不存在的 Windows 版本,应用程序应相应处理这种情况。
默认情况下,应用验证程序使用 7 作为主版本,3 作为次版本,0xe10 作为构建号。可通过更改测试设置的属性来配置这些设置,以下是可用属性及其说明:
| 属性 | 描述 |
| — | — |
| 主版本 | HighVersionLie 使用此属性的值作为主版本 |
| 次版本 | HighVersionLie 使用此属性的值作为次版本 |
| 构建号 | HighVersionLie 使用此属性的值作为构建号 |
| 服务包主版本 | HighVersionLie 使用此属性的值作为主要服务包版本 |
| 服务包次版本 | HighVersionLie 使用此属性的值作为次要服务包版本 |
| 套件掩码 | HighVersionLie 使用此属性的值作为套件掩码 |
| 产品类型 | HighVersionLie 使用此属性的值作为产品类型 |
| CSD 版本 | HighVersionLie 使用此属性的值作为 CSD 版本 |
此测试设置的停止代码均为占位符,用于指示测试设置已启用。
6. 交互式服务测试设置
服务通常在具有高权限的账户下运行,安全漏洞对系统的影响比低权限账户下的进程更大。攻击者可利用 Windows 的图形用户界面子系统进行攻击,如发送特定 Windows 消息以获取未授权访问。此测试设置可让用户快速判断服务是否为交互式服务或是否向其他应用程序发送用户界面元素。默认情况下,所有停止代码会将测试结果记录到日志文件中并包含调用栈。以下是相关的停止代码及其说明:
| 停止代码 | 测试 | 描述 |
| — | — | — |
| 00002800 | 交互式服务创建 | 当应用程序使用 CreateService API 创建交互式服务时触发,交互式服务可能存在安全风险 |
| 00002801 | 本地系统交互式服务 | 当应用程序在本地系统账户下作为交互式服务运行时触发,存在安全风险 |
| 00002802 | 使用 MessageBox API | 使用 MessageBox API 向交互式桌面发送通知可能是安全威胁 |
| 00002803 | 使用 MessageBoxEx API | 使用 MessageBoxEx API 向交互式桌面发送通知可能是安全威胁 |
| 00002804 | 交互式桌面 | 当应用程序调用 OpenWindowStation 和 OpenDesktop 向交互式桌面发送 UI 消息时触发,存在安全风险 |
| 00002805 | 交互式桌面 | 当应用程序调用 OpenDesktop 向交互式桌面发送 UI 消息时触发,存在安全风险 |
| 00002806 | 交互式桌面 | 当应用程序调用 OpenWindowStation 和 OpenInputDesktop 向交互式桌面发送 UI 消息时触发,存在安全风险 |
| 00002807 | 交互式桌面函数指针 | 当应用程序试图获取 OpenDesktop 函数的地址以向其发送 UI 消息时触发 |
7. 内核模式驱动程序安装测试设置
在 Windows 上,驱动程序在内核模式下运行,可访问系统关键数据。驱动程序失败可能对系统产生重大影响,甚至导致系统蓝屏。此测试设置可确保应用程序在安装驱动程序时使用正确的 API。默认情况下,所有与内核模式驱动程序安装相关的停止代码触发时不会使调试器中断,而是将停止代码和调用栈记录到日志文件中。以下是相关的停止代码及其说明:
| 停止代码 | 测试 | 描述 |
| — | — | — |
| 00002305 | 驱动程序安装 | 当调用 CreateServiceA 安装内核模式驱动程序时触发 |
| 00002306 | 文件系统过滤驱动程序 | 当调用 CreateServiceW 安装文件系统过滤驱动程序时触发 |
| 00002307 | 文件系统过滤驱动程序 | 当调用 CreateServiceA 安装文件系统过滤驱动程序时触发 |
| 00002308 | 驱动程序安装 | 当调用 CreateServiceW 安装内核模式驱动程序时触发 |
| 00002309 | 驱动程序安装 | 当应用程序未使用正确的 API(CreateService)安装驱动程序时触发 |
| 0000230A | 文件系统驱动程序安装 | 当应用程序未使用正确的 API(CreateService)安装文件系统驱动程序时触发 |
| 0000230B | 驱动程序安装 | 当应用程序未使用正确的 API(CreateService)安装驱动程序且未指定映像路径时触发 |
| 0000230C | 文件系统驱动程序安装 | 当应用程序未使用正确的 API(CreateService)安装文件系统驱动程序且未指定映像路径时触发 |
| 0000230D | 驱动程序安装 | 当应用程序未使用正确的 API(CreateService)安装驱动程序且未指定服务类型时触发 |
8. 低资源模拟测试设置
为确保应用程序的健壮性,它不仅要在正常系统负载下正常运行,还要在资源不足时表现良好。低资源模拟测试设置可帮助测试这种情况,允许开发者定义低资源故障在执行过程中发生的条件。该测试设置没有定义停止代码,而是允许修改多个测试设置参数。以下是相关参数及其说明:
| 属性 | 描述 |
| — | — |
| Include | 控制哪些 DLL 中会发生故障,DLL 应不包含路径,每行一个,可使用 * 表示所有模块都包含在故障注入中 |
| Exclude | 要从故障注入中排除的 DLL 列表,每行一个 |
| Timeout | 表示进程启动后在开始故障注入之前应经过的毫秒数 |
| WAIT | 一个 0 到 100 之间的数字,表示 WaitForXXX API 因故障注入而失败的概率 |
| HEAP_ALLOC | 一个 0 到 100 之间的数字,表示 HEAP_ALLOC API 因故障注入而失败的概率 |
| VIRTUAL_ALLOC | 一个 0 到 100 之间的数字,表示 VIRTUAL_ALLOC API 因故障注入而失败的概率 |
| REGISTRY | 一个 0 到 100 之间的数字,表示 REGISTRY API 因故障注入而失败的概率 |
| FILE | 一个 0 到 100 之间的数字,表示 FILE API 因故障注入而失败的概率 |
| EVENT | 一个 0 到 100 之间的数字,表示 EVENT API 因故障注入而失败的概率 |
| MAP_VIEW | 一个 0 到 100 之间的数字,表示 MAP_VIEW API 因故障注入而失败的概率 |
| OLE_ALLOC | 一个 0 到 100 之间的数字,表示 OLE_ALLOC API 因故障注入而失败的概率 |
| STACKS | 如果设置为 TRUE,表示应禁用栈增长功能以模拟低资源;如果设置为 FALSE,则允许栈增长 |
综上所述,这些测试设置为开发者提供了强大的工具,可帮助他们发现和解决各种编程错误,确保应用程序在不同环境下的稳定性和安全性。开发者可根据具体需求选择合适的测试设置,并根据需要调整相关参数。
各测试设置的使用建议与流程总结
8.1 各测试设置使用建议
-
内存测试设置
:在开发过程中,尤其是涉及大量内存操作的程序,如游戏开发、数据处理程序等,应始终开启此测试设置。通过
ExecWritePage属性,可进一步加强对可执行且可写内存的检查,避免潜在的安全漏洞。例如,在开发数据库管理系统时,内存的正确分配和释放至关重要,使用该测试设置能及时发现内存泄漏和无效内存访问等问题。 -
线程池测试设置
:当应用程序需要多线程处理任务时,如网络服务器程序、多线程计算程序等,开启线程池测试设置。同时,根据实际情况调整
AsyncCheck属性,确保对异步调用的检查。例如,在开发一个多用户在线聊天服务器时,线程池的正确使用能提高系统的并发处理能力,该测试设置可帮助检测线程池使用过程中的错误。 - TLS 测试设置 :对于使用线程本地存储的应用程序,如多线程日志记录程序、多线程配置管理程序等,开启此设置可确保 TLS 索引的正确使用,避免 TLS 索引泄漏和无效使用。
- 文件路径测试设置 :在开发涉及系统文件路径操作的应用程序时,如文件管理工具、系统安装程序等,开启该测试设置可确保获取的文件路径的正确性,避免因路径错误导致的程序崩溃。
- HighVersionLie 测试设置 :为了使应用程序具有更好的兼容性,在开发过程中开启此测试设置,模拟未来版本的 Windows 环境进行测试。根据需要调整相关属性,确保应用程序能正确处理不同版本的 Windows 系统。例如,在开发跨版本的办公软件时,使用该测试设置可提前发现版本兼容性问题。
- 交互式服务测试设置 :对于运行在高权限账户下的服务程序,如系统监控服务、安全防护服务等,开启此测试设置可及时发现交互式服务可能带来的安全风险,保障系统的安全性。
- 内核模式驱动程序安装测试设置 :在开发内核模式驱动程序时,如显卡驱动、硬盘驱动等,开启该测试设置可确保驱动程序的正确安装,避免因安装不当导致的系统蓝屏等严重问题。
- 低资源模拟测试设置 :为了提高应用程序的健壮性,在开发完成后,使用该测试设置模拟低资源环境进行测试。根据应用程序的特点,合理调整各个参数,确保应用程序在资源紧张的情况下仍能正常运行。例如,在开发移动应用时,模拟低内存、低电量等环境进行测试,可提高应用程序的稳定性。
8.2 使用流程总结
mermaid 流程图如下:
graph LR
classDef startend fill:#F5EBFF,stroke:#BE8FED,stroke-width:2px;
classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px;
classDef decision fill:#FFF6CC,stroke:#FFBC52,stroke-width:2px;
A([开始开发应用程序]):::startend --> B{选择测试设置}:::decision
B -->|内存操作多| C(内存测试设置):::process
B -->|多线程处理| D(线程池测试设置):::process
B -->|使用TLS| E(TLS测试设置):::process
B -->|涉及文件路径| F(文件路径测试设置):::process
B -->|关注版本兼容性| G(HighVersionLie测试设置):::process
B -->|高权限服务| H(交互式服务测试设置):::process
B -->|开发驱动程序| I(内核模式驱动程序安装测试设置):::process
B -->|测试健壮性| J(低资源模拟测试设置):::process
C --> K{是否需要调整属性}:::decision
D --> K
E --> K
F --> K
G --> K
H --> K
I --> K
J --> K
K -->|是| L(调整相关属性):::process
K -->|否| M(运行测试):::process
L --> M
M --> N{是否发现问题}:::decision
N -->|是| O(修复问题):::process
N -->|否| P([测试通过]):::startend
O --> M
总结
通过对这些应用验证程序测试设置的详细介绍,我们了解到它们在应用程序开发过程中的重要性。不同的测试设置针对不同类型的编程错误和潜在问题,开发者可以根据应用程序的特点和需求,有针对性地选择和使用这些测试设置。同时,合理调整测试设置的相关属性,能够更精准地发现和解决问题,确保应用程序在各种环境下都能稳定、安全地运行。在实际开发中,建议开发者将这些测试设置融入到开发流程中,定期进行测试,以提高应用程序的质量和可靠性。
超级会员免费看
5万+

被折叠的 条评论
为什么被折叠?



