bug 检查 0x139:KERNEL_SECURITY_CHECK_FAILURE

KERNEL_SECURITY_CHECK_FAILURE bug 检查的值为 0x00000139。 此 bug 检查指示内核检测到关键数据结构的损坏。

重要

这篇文章适合程序员阅读。 如果您是在使用计算机时收到蓝屏错误代码的客户,请参阅蓝屏错误疑难解答

bug 检查 0x139 KERNEL_SECURITY_CHECK_FAILURE 参数

参数 说明
1 损坏的类型。 有关详细信息,请参阅下表。
2 导致错误检查的异常的陷阱帧的地址
3 导致错误检查的异常的异常记录的地址
4 Reserved

下表对参数 1 的可能值进行了说明。

参数 1 说明
0 基于堆栈的缓冲区已溢出(旧版 /GS 违规)。
1 VTGuard 检测代码检测到使用非法虚拟函数表的尝试。 通常,C++ 对象已损坏,然后尝试使用损坏对象的指针进行虚拟方法调用。
2 堆栈 Cookie 检测代码检测到基于堆栈的缓冲区溢出(/GS 违规)。
3 LIST_ENTRY 已损坏(例如,双重删除)。 有关详细信息,请参阅以下“原因”部分。
4 Reserved
5 将无效参数传递给一个将无效参数视为致命参数的函数。
6 堆栈 Cookie 安全 Cookie 未由加载程序正确初始化。 这可能是因为生成驱动程序仅在 Windows 8 上运行,并尝试在早期版本的 Windows 上加载驱动程序映像。 若要避免此问题,必须生成要在早期版本的 Windows 上运行的驱动程序。
7 请求了致命程序退出。
8 编译器插入的数组边界检查检测到非法数组索引操作。
9 RtlQueryRegistryValues 的调用是在无 RTL_QUERY_REGISTRY_TYPECHECK 的情况下指定 RTL_QUERY_REGISTRY_DIRECT,并且目标值不在受信任的系统配置单元中。
10 间接呼叫临界检查检测到无效的控制传输。
11 写入临界检查检测到无效的内存写入。
12 尝试切换到无效的纤程上下文。
13 已尝试分配无效的寄存器上下文。
14 对象的引用计数无效。
18 尝试切换到无效的 jmp_buf 上下文。
19 对只读数据进行了不安全的修改。
20 加密自我测试失败。
21 检测到无效的异常链。
22 发生加密库错误。
23 在 DllMain 中进行了无效的调用。
24 检测到无效的映像基址。
25 保护延迟加载导入时遇到无法恢复的失败。
26 已调用不安全的扩展。
27 调用了已弃用的服务。
28 检测到超出边界的缓冲区访问。
29 RTL_BALANCED_NODE RBTree 条目已损坏。
37 调用了超出范围的开关跳转项。
38 longjmp 尝试到无效的目标。
39 无法将导出禁止调用目标作为有效的呼叫目标。

原因

使用参数 1 表和转储文件,可以缩小此类型许多 bug 检查的原因。

LIST_ENTRY 损坏可能难以跟踪,并且此 bug 检查表明已将不一致引入到一个双重链接的列表中(在向列表中添加或删除单个列表条目元素时检测到)。 遗憾的是,在损坏发生时不一定检测到不一致,因此可能需要一些侦探工作来确定根本原因。

列表项损坏的常见原因包括:

  • 驱动程序损坏了内核同步对象,例如 KEVENT(例如,在线程仍在等待同一 KEVENT 时初始化 KEVENT,或者允许基于堆栈的 KEVENT 在使用该 KEVENT 时超出范围)。 这种类型的 bug 检查通常发生在 nt!Ke* 或 nt!Ki* 代码。 当线程完成等待同步对象或代码尝试将同步对象置于信号状态时,可能会发生这种情况。 通常,要发出信号的同步对象是已损坏的同步对象。 有时,具有特殊池的驱动程序验证程序可以帮助跟踪罪魁祸首(如果损坏的同步对象位于已释放的池块中)。
  • 驱动程序已损坏定期 KTIMER。 这种类型的 bug 检查通常发生在 nt!Ke* 或 nt!Ki* 代码,并涉及向计时器发出信号,或者插入或删除计时器表中的计时器。 正在操作的计时器可能是损坏的计时器,但可能需要使用 !timer 检查计时器表(或手动遍历计时器列表链接),以确定哪些计时器已损坏。 有时,具有特殊池的驱动程序验证程序可以帮助跟踪罪魁祸首(如果损坏的 KTIMER 位于已释放的池块中)。
  • 驱动程序管理不良好的内部 LIST_ENTRY 样式链接列表。 典型的示例是在同一列表条目上调用 RemoveEntryList 两次,而无需重新插入两个 RemoveEntryList 调用之间的列表项。 其他变体可行,例如将条目插入到同一列表中。
  • 驱动程序释放了包含 LIST_ENTRY 的数据结构,而不会从其相应的列表中删除数据结构,导致在旧池块重复使用后检查列表后检测到损坏。
  • 驱动程序以并发方式使用 LIST_ENTRY 样式的列表,而无需进行适当的同步,从而对列表进行撕裂更新。

在大多数情况下,可以通过向前和向后走链接列表(dldlb 命令可用于此目的)和比较结果来确定损坏的数据结构。 如果列表在向前和向后走之间不一致,通常是损坏的位置。 由于链接列表更新操作可以修改相邻元素的列表链接,因此应仔细查看损坏的列表条目的邻居,因为它们可能是基础罪魁祸首。

由于许多系统组件在内部利用 LIST_ENTRY 列表,因此使用系统 API 的驱动程序进行各种类型的资源管理不当可能会导致系统管理的链接列表损坏。

解决方法

确定此问题的原因通常需要使用调试器来收集其他信息。 应检查多个转储文件,以查看此停止代码是否具有类似的特征,例如在停止代码出现时运行的代码。

有关详细信息,请参阅使用 Windows 调试器 (WinDbg) 进行崩溃转储分析使用 !analyze 扩展!analyze

使用事件日志查看是否存在导致此停止代码的更高级别事件。

这些常规故障排除提示可能会有所帮助。

  • 如果最近向系统添加了硬件,请尝试删除或替换它。 或与制造商联系,查看是否有可用的修补程序。

  • 如果最近添加了新的设备驱动程序或系统服务,请尝试删除或更新它们。 尝试确定系统中导致新 Bug 检查代码出现的原因。

  • 检查事件查看器中的系统日志,以获取可能有助于查明导致错误的设备或驱动程序的其他错误消息。 有关详细信息,请参阅打开事件查看器。 在系统日志中查找与蓝屏同时出现的严重错误。

  • 设备管理器中查看是否有任何设备标有感叹号 (!)。 查看驱动程序属性中显示的事件日志,以查找任何故障驱动程序。 请尝试更新相关驱动程序。

  • 运行病毒检测程序。 病毒可感染针对 Windows 格式化的所有类型的硬盘,由此导致的磁盘损坏可能会生成系统 Bug 检查代码。 确保病毒检测程序检查主启动记录是否存在感染。

  • 有关其他常规故障排除信息,请参阅蓝屏数据

另请参阅

使用 Windows 调试器 (WinDbg) 进行故障转储分析

使用 WinDbg 分析内核模式转储文件