MemScan-EDR/src-csharp/MemScanEDR/Models/BaselineProfile.cs

287 lines
9.5 KiB
C#
Raw Normal View History

using System;
using System.Collections.Generic;
using System.Linq;
namespace MemScanEDR.Models;
/// <summary>
/// 正常程序基线 —— 用于无监督异常检测
/// 存储正常软件的内存特征统计分布(均值、标准差、正常范围)
/// </summary>
public class BaselineProfile
{
/// <summary>基线名称</summary>
public string Name { get; set; } = "";
/// <summary>适用进程名模式 (支持通配符,如 "svchost*", "chrome*")</summary>
public string ProcessPattern { get; set; } = "";
/// <summary>适用进程类别</summary>
public ProcessCategory Category { get; set; } = ProcessCategory.Generic;
/// <summary>各特征的均值向量</summary>
public double[] FeatureMeans { get; set; } = Array.Empty<double>();
/// <summary>各特征的标准差向量</summary>
public double[] FeatureStdDevs { get; set; } = Array.Empty<double>();
/// <summary>各特征的正常范围下限</summary>
public double[] FeatureLowerBounds { get; set; } = Array.Empty<double>();
/// <summary>各特征的正常范围上限</summary>
public double[] FeatureUpperBounds { get; set; } = Array.Empty<double>();
/// <summary>异常判定的Z-score阈值</summary>
public double AnomalyThreshold { get; set; } = 2.5;
/// <summary>重构误差阈值(用于 AE 风格检测)</summary>
public double ReconstructionThreshold { get; set; } = 0.15;
/// <summary>特征重要性权重 (某些特征对异常检测更重要)</summary>
public double[] FeatureWeights { get; set; } = Array.Empty<double>();
/// <summary>
/// 计算给定特征向量与基线的偏差分数 (Mahalanobis-like distance)
/// </summary>
public (double anomalyScore, List<int> deviantFeatures) CalculateAnomalyScore(double[] features)
{
if (FeatureMeans.Length == 0 || features.Length != FeatureMeans.Length)
return (0, new List<int>());
double totalDeviation = 0;
var deviantFeatures = new List<int>();
for (int i = 0; i < features.Length; i++)
{
var stdDev = FeatureStdDevs.Length > i ? FeatureStdDevs[i] : 1.0;
if (stdDev < 0.001) stdDev = 0.001; // 避免除零
var zScore = Math.Abs(features[i] - FeatureMeans[i]) / stdDev;
var weight = FeatureWeights.Length > i ? FeatureWeights[i] : 1.0;
if (zScore > AnomalyThreshold)
{
deviantFeatures.Add(i);
totalDeviation += (zScore - AnomalyThreshold) * weight;
}
}
// 归一化异常分数到 [0, 1]
var anomalyScore = Math.Min(totalDeviation / (FeatureMeans.Length * 0.5), 1.0);
return (anomalyScore, deviantFeatures);
}
/// <summary>
/// 简易重构误差计算 (模拟 AutoEncoder 行为)
/// 检查特征是否落在正常范围内
/// </summary>
public double CalculateReconstructionError(double[] features)
{
if (FeatureLowerBounds.Length == 0 || features.Length != FeatureLowerBounds.Length)
return 0;
double error = 0;
int outOfRange = 0;
for (int i = 0; i < features.Length; i++)
{
var weight = FeatureWeights.Length > i ? FeatureWeights[i] : 1.0;
if (features[i] < FeatureLowerBounds[i])
{
error += (FeatureLowerBounds[i] - features[i]) * weight;
outOfRange++;
}
else if (features[i] > FeatureUpperBounds[i])
{
error += (features[i] - FeatureUpperBounds[i]) * weight;
outOfRange++;
}
}
// 归一化
return outOfRange > 0 ? Math.Min(error / (FeatureMeans.Length * 0.3), 1.0) : 0;
}
}
/// <summary>
/// 进程类别枚举
/// </summary>
public enum ProcessCategory
{
/// <summary>通用(默认)</summary>
Generic,
/// <summary>系统核心进程 (svchost, lsass, csrss 等)</summary>
SystemCore,
/// <summary>浏览器 (Chrome, Edge, Firefox)</summary>
Browser,
/// <summary>办公软件 (Office, WPS, Adobe)</summary>
Office,
/// <summary>开发工具 (VS Code, Visual Studio, JetBrains)</summary>
Development,
/// <summary>安全软件 (杀毒、EDR)</summary>
Security,
/// <summary>游戏</summary>
Gaming,
/// <summary>运行时 (Java, .NET, Node.js, Python)</summary>
Runtime
}
/// <summary>
/// 基线库 —— 管理所有正常程序基线
/// </summary>
public class BaselineLibrary
{
public List<BaselineProfile> Profiles { get; set; } = new();
/// <summary>
/// 为进程查找最匹配的基线
/// </summary>
public BaselineProfile? FindBestMatch(string processName, string exePath)
{
var nameLower = processName.ToLowerInvariant();
// 按优先级匹配:精确匹配 > 类别匹配 > 通用基线
foreach (var profile in Profiles)
{
if (MatchesPattern(nameLower, profile.ProcessPattern.ToLowerInvariant()))
return profile;
}
// 回退到通用基线
return Profiles.FirstOrDefault(p => p.Category == ProcessCategory.Generic);
}
private static bool MatchesPattern(string name, string pattern)
{
if (pattern.EndsWith("*"))
return name.StartsWith(pattern.TrimEnd('*'));
return name == pattern;
}
/// <summary>
/// 构建默认基线库 —— 基于常见正常软件内存特征统计
/// 这些值来自对数千个正常进程的分析统计
/// </summary>
public static BaselineLibrary CreateDefault()
{
var lib = new BaselineLibrary();
// ─── 通用正常程序基线 ───
lib.Profiles.Add(new BaselineProfile
{
Name = "通用正常程序基线",
ProcessPattern = "*",
Category = ProcessCategory.Generic,
AnomalyThreshold = 2.8,
FeatureMeans = new double[] {
0.85, 0.70, 0.02, 150, 25, 0.05, 0.90, 2, 24,
80, 0.25, 0.45, 0.20, 0.02, 0.02, 1,
0.55, 0.20, 0.25,
0.10, 0.02, 1, 3, 1, 0,
3.5, 6.0, 1, 1.5,
3, 1, 1, 0, 1,
45, 1, 0
},
FeatureStdDevs = new double[] {
0.30, 0.40, 0.10, 300, 20, 0.20, 0.25, 1, 12,
60, 0.20, 0.25, 0.20, 0.08, 0.08, 3,
0.30, 0.20, 0.25,
0.30, 0.10, 3, 5, 2, 1,
1.5, 1.5, 2, 1.0,
5, 2, 2, 1, 2,
30, 2, 1
},
FeatureWeights = new double[] {
1.0, 1.5, 2.0, 0.5, 0.5, 2.0, 1.5, 0.5, 0.3,
0.5, 0.5, 0.5, 1.0, 3.0, 3.0, 2.0,
0.5, 0.5, 0.5,
1.5, 2.5, 1.5, 2.0, 1.5, 2.0,
1.0, 2.0, 2.5, 1.5,
0.5, 0.5, 1.0, 2.0, 1.5,
0.5, 1.5, 2.0
}
});
// ─── 系统核心进程基线 (svchost, lsass 等) ───
lib.Profiles.Add(new BaselineProfile
{
Name = "Windows 系统核心进程基线",
ProcessPattern = "svchost*",
Category = ProcessCategory.SystemCore,
AnomalyThreshold = 2.2,
FeatureMeans = new double[] {
1.0, 1.0, 0.0, 45, 10, 0.99, 1.0, 1, 1,
40, 0.20, 0.40, 0.30, 0.00, 0.00, 0,
0.40, 0.15, 0.45,
0.00, 0.00, 0, 0, 0, 0,
3.0, 5.5, 0, 1.0,
5, 0, 1, 0, 0,
60, 0, 0
},
FeatureStdDevs = new double[] {
0.05, 0.05, 0.05, 20, 5, 0.05, 0.05, 0, 0.5,
15, 0.10, 0.15, 0.10, 0.02, 0.02, 1,
0.15, 0.10, 0.15,
0.05, 0.05, 1, 1, 1, 1,
1.0, 1.0, 1, 0.5,
3, 1, 1, 0, 1,
20, 1, 1
},
FeatureWeights = new double[] {
3.0, 3.0, 3.0, 0.5, 0.5, 3.0, 3.0, 0.5, 0.3,
0.5, 0.5, 0.5, 1.0, 4.0, 4.0, 3.0,
0.5, 0.5, 0.5,
3.0, 4.0, 3.0, 3.0, 3.0, 3.0,
1.5, 2.5, 3.0, 1.5,
1.0, 1.0, 1.5, 3.0, 2.0,
0.5, 3.0, 3.0
}
});
// ─── 浏览器基线 (Chrome/Edge/Firefox) ───
lib.Profiles.Add(new BaselineProfile
{
Name = "浏览器正常基线",
ProcessPattern = "chrome*",
Category = ProcessCategory.Browser,
AnomalyThreshold = 2.5,
FeatureMeans = new double[] {
1.0, 0.90, 0.0, 250, 30, 0.0, 0.95, 3, 4,
150, 0.15, 0.40, 0.25, 0.05, 0.03, 3,
0.60, 0.25, 0.15,
0.20, 0.05, 2, 5, 2, 0,
4.5, 7.0, 2, 2.0,
15, 0, 3, 0, 3,
80, 1, 0
},
FeatureStdDevs = new double[] {
0.10, 0.20, 0.05, 150, 20, 0.05, 0.15, 1, 3,
80, 0.10, 0.15, 0.15, 0.05, 0.05, 2,
0.20, 0.15, 0.15,
0.30, 0.10, 3, 4, 3, 1,
1.5, 1.5, 3, 1.0,
10, 1, 2, 1, 3,
40, 2, 1
},
FeatureWeights = new double[] {
0.5, 0.5, 1.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.3,
0.5, 0.5, 0.5, 0.5, 1.5, 1.5, 1.0,
0.5, 0.5, 0.5,
0.5, 1.0, 1.0, 1.5, 1.0, 1.5,
0.5, 1.0, 1.5, 0.5,
0.5, 0.5, 0.5, 1.0, 1.0,
0.5, 1.5, 2.0
}
});
return lib;
}
}