Windows 蓝屏代码 0x139 KERNEL_SECURITY_CHECK_FAILURE 参数
参数 | 描述 |
---|---|
1 | 损坏的类型。有关详细信息,请参阅下表。 |
2 | 导致错误检查的异常的陷阱帧的 |
3 | 地址导致错误检查的异常的异常记录的地址 |
4 | 保留 |
下表描述了参数 1 的可能值。
参数 1 | 描述 |
---|---|
0 | 基于堆栈的缓冲区已溢出(遗留/GS 违规)。 |
1 | VTGuard 检测代码检测到尝试使用非法虚拟函数表。通常,C++ 对象已损坏,然后尝试使用损坏对象的 this 指针进行虚拟方法调用。 |
2 | 堆栈 cookie 检测代码检测到基于堆栈的缓冲区溢出(/GS 违规)。 |
3 | LIST_ENTRY 已损坏(例如,双重删除)。有关详细信息,请参阅以下原因部分。 |
4 | 保留 |
5 | 将无效参数传递给认为无效参数致命的函数。 |
6 | 加载程序未正确初始化堆栈 cookie 安全 cookie。这可能是由于构建仅在 Windows 8 上运行的驱动程序并尝试在早期版本的 Windows 上加载驱动程序镜像造成的。为避免此问题,我们必须构建驱动程序以在较早版本的 Windows 上运行。 |
7 | 请求了一个致命的程序退出。 |
8 | 编译器插入的数组边界检查检测到非法的数组索引操作。 |
9 | 调用 RtlQueryRegistryValues 指定 RTL_QUERY_REGISTRY_DIRECT 而没有 RTL_QUERY_REGISTRY_TYPECHECK,并且目标值不在受信任的系统配置单元中。 |
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 表和转储文件,可以缩小许多此类错误检查的原因。
LIST_ENTRY 损坏可能难以追踪,此错误检查表明已将不一致性引入双向链接列表(在将单个列表条目元素添加到列表或者从列表中删除时检测到)。
不幸的是,在损坏发生时不一定检测到不一致,因此可能需要一些侦探工作来确定根本原因。
列表条目损坏的常见原因包括:
- 驱动程序损坏了内核同步对象,例如 KEVENT(例如,在线程仍在等待同一个 KEVENT 时对 KEVENT 进行双重初始化,或者当另一个线程正在使用该 KEVENT 时允许基于堆栈的 KEVENT 超出范围)。这种类型的错误检查通常发生在 nt!Ke* 或者 nt!Ki* 代码中。当线程完成对同步对象的等待或者代码尝试将同步对象置于信号状态时,就会发生这种情况。通常,发出信号的同步对象是已损坏的对象。有时,具有特殊池的驱动程序验证程序可以帮助追踪罪魁祸首(如果损坏的同步对象位于已被释放的池块中)。
- 驱动程序损坏了定期 KTIMER。这种类型的错误检查通常发生在 nt!Ke* 或者 nt!Ki* 代码中,涉及发送计时器信号,或者从计时器表中插入或者删除计时器。被操纵的计时器可能是损坏的计时器,但可能需要使用 !timer 检查计时器表(或者手动遍历计时器列表链接)以确定哪个计时器已损坏。
有时,具有特殊池的驱动程序验证程序可以帮助追踪罪魁祸首(如果损坏的 KTIMER 位于已被释放的池块中)。
- 驱动程序对内部 LIST_ENTRY 样式的链表管理不善。一个典型的例子是在同一个列表条目上调用 RemoveEntryList 两次,而不在两次 RemoveEntryList 调用之间重新插入列表条目。其他变体也是可能的,例如将条目双重插入到同一列表中。
- 驱动程序释放了一个包含 LIST_ENTRY 的数据结构,但没有从其对应的列表中删除数据结构,导致在重用旧池块后检查列表时会检测到损坏。
- 驱动程序在没有适当同步的情况下以并发方式使用了 LIST_ENTRY 样式的列表,从而导致对列表的更新撕裂。
在大多数情况下,我们可以通过向前和向后遍历链表(dl 和 dlb 命令用于此目的)并比较结果来识别损坏的数据结构。
向前和向后行走之间的列表不一致的地方通常是损坏的位置。
由于链表更新操作可以修改相邻元素的列表链接,因此我们应该仔细查看损坏的列表条目的邻居,因为它们可能是潜在的罪魁祸首。
由于许多系统组件在内部使用 LIST_ENTRY 列表,驱动程序使用系统 API 的各种类型的资源管理不当可能会导致系统管理的链表中的链表损坏。
解决方法
确定此问题的原因通常需要使用调试器来收集其他信息。
应检查多个转储文件以查看此停止代码是否具有相似的特征,例如停止代码出现时正在运行的代码。
有关详细信息,请参阅使用 Windows 调试器 (WinDbg) 进行崩溃转储分析、使用 !analyze 扩展和 !analyze :
在windows 中使用WinDBG 调试dmp文件
使用事件日志查看是否存在导致此停止代码的更高级别的事件。
这些一般故障排除提示可能会有所帮助。
- 如果我们最近向系统添加了硬件,请尝试移除或者更换它。或者与制造商联系以查看是否有可用的补丁。
- 如果最近添加了新的设备驱动程序或者系统服务,请尝试删除或者更新它们。尝试确定系统中导致新错误检查代码出现的更改。
- 检查事件查看器中的系统日志以获取可能有助于查明导致错误的设备或者驱动程序的其他错误消息。有关更多信息,请参阅打开事件查看器。
在系统日志中查找与蓝屏在同一时间窗口中发生的严重错误。
- 在设备管理器中查看是否有任何设备标有感叹号 (!)。查看驱动程序属性中显示的任何故障驱动程序的事件日志。尝试更新相关驱动程序。
- 运行病毒检测程序。病毒可以感染为 Windows 格式化的所有类型的硬盘,由此导致的磁盘损坏会生成系统错误检查代码。确保病毒检测程序检查主引导记录是否存在感染。
- 有关其他常规故障排除信息,请参阅蓝屏数据。
KERNEL_SECURITY_CHECK_FAILURE 错误检查的值为 0x00000139.
此错误检查表明内核已检测到关键数据结构的损坏。