BSOD Dump 分析 - EPSVHRule.dll 系统卡死调查

Dump 基本信息

字段
系统Windows 7 SP1 x64 (Build 7601.24384)
Build Lab7601.24384.amd64fre.win7sp1_ldr_escrow.190220-1800
崩溃时间2026-07-31 15:30:29 (UTC+8)
系统运行时长0天 0:12:14(崩溃前运行约12分钟)
Dump 类型Kernel Summary Dump
Dump 文件D:\Montarius\Downloads\MEMORY\MEMORY.DMP (205MB)
CPU单处理器 (UP Free x64)
产品WinNt, suite: TerminalServer SingleUserTS
内核基址fffff800'03e63000
PsLoadedModuleListfffff800'0409cc90

崩溃原因

**BugCheck 0x000000E2 — MANUALLY_INITIATED_CRASH **

手动触发的蓝屏(系统卡死后手动制造 dump)。所有参数均为 0。

BugCheck Code: 0xE2 (MANUALLY_INITIATED_CRASH)
Parameters: 0, 0, 0, 0

调用栈分析

Child-SP          RetAddr               : Args to Child                                                           : Call Site
fffff800'054b58c8 fffff880'055e2dd2     : 00000000'000000e2 00000000'00000000 00000000'00000000 00000000'00000000 : nt!KeBugCheckEx
fffff800'054b58d0 fffff880'055dddf1     : fffffa80'19442970 00000000'00000004 fffff800'054b5a10 00000000'00000002 : i8042prt+0x7dd2
fffff800'054b5910 fffff800'03ef7808     : 00000000'00000000 fffffa80'19442820 fffffa80'191cfbc6 fffffa80'19442cf4 : i8042prt+0x2df1
fffff800'054b5990 fffff880'052d8ae2     : fffff880'052d7a3c fffffa80'19a3bb20 fffff880'0565d5c1 fffffa80'199e25d0 : nt!KeSynchronizeExecution+0x4d8 (TrapFrame @ fffff800'054b5990)
fffff800'054b5b28 fffff880'052d7a3c     : fffffa80'19a3bb20 fffff880'0565d5c1 fffffa80'199e25d0 fffffa80'199e2480 : intelppm+0x3ae2
fffff800'054b5b30 fffff800'03fad174     : 00000000'00000000 fffffa80'193fee30 fffff800'040571c0 00000000'00000001 : intelppm+0x2a3c
fffff800'054b5b60 fffff800'03efa0ec     : fffff800'04047180 fffff800'040571c0 00000000'00000000 fffff880'0565d588 : nt!WmiTraceMessageVa+0xe74
fffff800'054b5c40 00000000'00000000     : fffff800'054b6000 fffff800'054b0000 fffff800'054b5c00 00000000'00000000 : nt!KiCpuId+0x114c

调用栈解读

#地址模块说明
0nt!KeBugCheckExntoskrnl蓝屏入口,BugCheck 0xE2
1i8042prt+0x7dd2i8042prt.sysPS/2 键盘控制器驱动,触发手动崩溃
2i8042prt+0x2df1i8042prt.sysi8042prt 内部调用
3nt!KeSynchronizeExecution+0x4d8ntoskrnl内核同步执行(自旋锁等)
4intelppm+0x3ae2intelppm.sysIntel CPU 电源管理
5intelppm+0x2a3cintelppm.sysIntel PPM 内部
6nt!WmiTraceMessageVa+0xe74ntoskrnlWMI 跟踪消息
7nt!KiCpuId+0x114cntoskrnlCPU ID 指令(Idle 循环)

调用栈结论:这是系统 Idle 线程被手动中断的栈。i8042prt 键盘驱动收到手动触发命令后调用 KeBugCheckEx(0xE2, ...)此栈本身不包含 EPSVHRule.dll 的调用——这是预期的,因为系统卡死时 EPSVHRule 可能持有锁或处于死循环,但当前 CPU 栈是 Idle 线程。

已加载 360 模块清单

lm 输出中提取所有 360 相关驱动:

模块名起始地址结束地址大小说明
360AntiSteal64fffff880'0162b000fffff880'0163900056 KB防盗号
360Box64fffff880'01639000fffff880'01693000368 KB沙箱
360netmonfffff880'04400000fffff880'0445d000372 KB网络监控
360FsFltfffff880'04460000fffff880'04545000660 KB文件系统过滤
360AntiExploit64fffff880'05200000fffff880'0526c000432 KB漏洞防护
360AntiHijack64fffff880'0539a000fffff880'053b5000108 KB防劫持
360AntiHacker64fffff880'053b5000fffff880'053ec000216 KB防黑客
360Hvm64fffff880'05441000fffff880'05517000856 KBHVM(虚拟化防护)
360qpesv64fffff880'05560000fffff880'055b5000344 KBQPE(主动防御引擎)
360Sensor64fffff880'06671000fffff880'0667c00044 KB传感器

已卸载的 360 模块

模块名起始地址结束地址说明
360Sensor64.sysfffff880'067d4000fffff880'067df000传感器(已卸载)

关键发现

EPSVHRule.dll 未出现在已加载模块列表中。

EPSVHRule.dll 的路径是 C:\Program Files (x86)\360\360Safe\safemon\EPSVHRule.dll,属于 360 安全卫士的 safemon(安全监控)组件。它是一个 用户态 DLL,不是内核驱动。

Kernel Summary Dump 主要包含内核地址空间,用户态内存可能不可用(dump 头部明确说 “User address space may not be available”)。因此:

  1. EPSVHRule.dll 作为用户态模块,不会出现在 lm 的内核模块列表中
  2. 在 Kernel Summary Dump 中搜索用户态字符串(s -a 搜索)返回全 ????????,因为大部分用户态页面未包含在 dump 中
  3. 要分析 EPSVHRule.dll 的调用栈,需要 Complete Memory Dump 或至少包含用户态空间的 dump

符号问题说明

此 dump 分析中遇到严重的符号问题:

问题原因
ntkrnlmp 符号找不到Win7 SP1 的 PDB 未正确下载或版本不匹配
i8042prt 符号找不到同上
!analyze -v 不可用kdexts.dll 加载失败(Win10 SDK 的 kdexts 不兼容 Win7 dump)
dt nt!_EPROCESS 失败没有 PDB 类型信息
!process 0 0 失败同上

解决方案(在 Windows 端使用 WinDbg 时)

在 WinDbg 中打开此 dump 后,执行以下命令修复符号:

windbg
// 设置符号路径(指向微软符号服务器 + 本地缓存)
.sympath srv*C:\symbols*https://msdl.microsoft.com/download/symbols
 
// 重新加载符号
.reload /f nt
.reload /f i8042prt
.reload /f intelppm
 
// 加载 Win7 兼容的 kdexts(从 Win8.1 SDK 复制)
.load C:\Users\Montarius\kdexts.dll
 
// 现在可以运行分析
!analyze -v

在 WinDbg 中手动复现分析的命令

在 Windows 端打开 WinDbg(或 kd),加载 dump 文件后依次执行:

windbg
// ========== 1. 基本设置 ==========
.sympath srv*C:\symbols*https://msdl.microsoft.com/download/symbols
.reload
.load C:\Users\Montarius\kdexts.dll
 
// ========== 2. 自动分析(如果符号正常) ==========
!analyze -v
 
// ========== 3. 查看调用栈 ==========
kv 50          // 当前线程栈(带帧指针)
~              // 列出所有处理器(本机为单 CPU)
 
// ========== 4. 查看所有已加载模块 ==========
lm             // 全部模块
lm m 360*      // 仅 360 相关模块
lm m EPSVH*    // 搜索 EPSVHRule(用户态,可能找不到)
 
// ========== 5. 搜索 EPSVHRule 相关内存 ==========
// 注意:Kernel Summary Dump 中大部分用户态内存不可用
// 如果是 Complete Dump,可以尝试:
s -a 0 L?7fffffffffff EPSVHRule
s -u 0 L?7fffffffffff EPSVHRule
s -a 0 L?7fffffffffff C:\Program Files (x86)\360\360Safe\safemon\EPSVHRule
s -u 0 L?7fffffffffff C:\Program Files (x86)\360\360Safe\safemon\EPSVHRule
 
// ========== 6. 搜索 360 safemon 相关字符串 ==========
s -a 0 L?7fffffffffff 360Safe
s -a 0 L?7fffffffffff safemon
s -a 0 L?7fffffffffff EPSVH
 
// ========== 7. 手动遍历进程列表(Win7 SP1 x64 偏移) ==========
// 如果 !process 0 0 因符号失败,手动遍历:
// EPROCESS 偏移:PID=+0x180, Links=+0x188, Name=+0x2d0, Threads=+0x308
 
// System EPROCESS
x nt!PsInitialSystemProcess
// 假设返回 fffff800`04100028
 
// System PID
dq fffff800`04100028+0x180 L1
 
// System Name
dc fffff800`04100028+0x2d0 L4
 
// ActiveProcessLinks.Flink(第一个进程)
dq fffff800`04100028+0x188 L1
// 返回值 X 指向下一个 EPROCESS+0x188
// 用 X-0x188 得到下一个 EPROCESS 基址,重复遍历
 
// ========== 8. 遍历线程列表 ==========
// 对每个 EPROCESS,ThreadListHead 在 +0x308
// ETHREAD.ThreadListEntry 在 +0x428
// 遍历双向链表,对每个 ETHREAD:
//   KTHREAD.StackBase   = +0x038
//   KTHREAD.InitialStack = +0x028
//   KTHREAD.TrapFrame   = +0x0d8
 
// ========== 9. 检查锁等待 ==========
// 系统卡死通常涉及自旋锁死锁或 DPC 阶段阻塞
// 检查每个线程的 WaitReason 和等待的锁
 
// ========== 10. 检查 DPC 队列 ==========
// 如果卡死发生在 DPC 级别,检查 DPC 队列
// 每个 CPU 的 PRCB 中有 DpcList
// KPCR.PrcbData.DpcListHead(Win7 x64 偏移需查 PDB)

如果需要分析 EPSVHRule.dll(用户态)

由于当前是 Kernel Summary Dump,无法直接分析用户态调用栈。要分析 EPSVHRule.dll 的调用:

  1. 生成 Complete Memory Dump

    • 注册表设置 CrashDumpEnabled = 1(Complete)
    • 或使用 NotMyFault 工具触发
  2. 使用 LiveKD / 进程转储

    • 在系统卡死但未蓝屏时,用另一台机器通过 KDNET 连接
    • 或用 procdump -ma 抓取 360 安全卫士进程的完整转储
  3. 在 Complete Dump 中分析

    windbg
    // 查找 360tray.exe / 360sdsext.exe 等加载了 EPSVHRule.dll 的进程
    !process 0 0 360*
     
    // 进入目标进程上下文
    .process /p fffffa80`xxxxxxxx
     
    // 检查 EPSVHRule.dll 的加载基址
    !dh fffff880'xxxxxxxx -f
     
    // 查看调用栈中是否有 EPSVHRule 的帧
    // 搜索线程栈中的返回地址

360 模块地址速查(供 WinDbg 手动分析用)

360AntiSteal64   fffff880'0162b000 - fffff880'01639000  (56 KB)
360Box64         fffff880'01639000 - fffff880'01693000  (368 KB)
360netmon        fffff880'04400000 - fffff880'0445d000  (372 KB)
360FsFlt         fffff880'04460000 - fffff880'04545000  (660 KB)
360AntiExploit64 fffff880'05200000 - fffff880'0526c000  (432 KB)
360AntiHijack64  fffff880'0539a000 - fffff880'053b5000  (108 KB)
360AntiHacker64  fffff880'053b5000 - fffff880'053ec000  (216 KB)
360Hvm64         fffff880'05441000 - fffff880'05517000  (856 KB)
360qpesv64       fffff880'05560000 - fffff880'055b5000  (344 KB)
360Sensor64      fffff880'06671000 - fffff880'0667c000  (44 KB)
i8042prt         fffff880'055db000 - fffff880'055f9000  (120 KB)
intelppm         fffff880'052d5000 - fffff880'052eb000  (88 KB)

关键结论

  1. Dump 类型限制:当前是 Kernel Summary Dump,用户态内存不可用,无法直接看到 EPSVHRule.dll 的调用栈
  2. 崩溃机制:手动触发(BugCheck 0xE2),通过 i8042prt 键盘驱动
  3. 当前 CPU 栈是 Idle 线程:系统卡死时 CPU 可能在 Idle 循环中,真正的卡死原因可能在其他线程或锁等待中
  4. 下一步建议
    • 在 WinDbg 中用正确符号重新打开,运行 !analyze -v 获取完整线程列表
    • 如果能获得 Complete Dump,重点检查 360 安全卫士相关进程的线程栈
    • 检查 360 内核驱动(360Hvm64、360qpesv64、360FsFlt 等)是否有锁等待或 DPC 超时

分析环境

调试器CDB 10.0.26100.1 AMD64
调试器路径C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\cdb.exe
kdexts.dll从 Win8.1 SDK 复制 (6.3.9600.17298)
符号路径SRV*C:\symbols*https://msdl.microsoft.com/download/symbols
分析脚本C:\Users\Montarius\run_cdb.ps1
分析输出C:\Users\Montarius\bsod_epsvh_full.txt