MemScan-EDR/src-csharp/MemScanEDR/Services/EntropyAnalyzer.cs

146 lines
4.7 KiB
C#
Raw Permalink Normal View History

using System;
using System.Runtime.InteropServices;
using MemScanEDR.Models;
namespace MemScanEDR.Services;
/// <summary>
/// 熵值分析器 —— 计算内存区域的 Shannon 熵
/// 高熵 (>7.0) 通常表示加密/压缩载荷,是恶意软件的重要指标
/// 正常程序代码段熵值通常稳定在 3.0-6.5 范围
/// </summary>
public class EntropyAnalyzer
{
// Entropy calculation constants
private const int SampleSize = 4096; // 默认采样大小
private const int MaxSamplesPerRegion = 8; // 每个区域最多采样点
private const double HighEntropyThreshold = 7.0;
private const uint PROCESS_VM_READ = 0x0010;
/// <summary>
/// 计算单个内存区域的熵值(通过采样子区域)
/// </summary>
public double CalculateRegionEntropy(IntPtr hProcess, ulong baseAddress, ulong regionSize)
{
if (regionSize == 0) return 0;
var entropies = new List<double>();
var sampleCount = Math.Min(MaxSamplesPerRegion, (int)(regionSize / SampleSize));
if (sampleCount < 1) sampleCount = 1;
for (int i = 0; i < sampleCount; i++)
{
var offset = (ulong)(i * (long)(regionSize / (ulong)sampleCount));
var readSize = Math.Min(SampleSize, regionSize - offset);
if (readSize > int.MaxValue) readSize = SampleSize;
var buffer = new byte[readSize];
if (ReadProcessMemory(hProcess, (IntPtr)(baseAddress + offset), buffer, (int)readSize, out _))
{
entropies.Add(CalculateShannonEntropy(buffer));
}
}
return entropies.Count > 0 ? entropies.Average() : 0;
}
/// <summary>
/// 批量计算所有内存区域的熵值,更新 MemoryRegion.Entropy 字段
/// </summary>
public EntropyResult AnalyzeRegions(IntPtr hProcess, List<MemoryRegion> regions)
{
var result = new EntropyResult();
var allEntropies = new List<double>();
foreach (var region in regions)
{
// 只对已提交的可读区域计算熵
if (region.State != "COMMIT") continue;
if (region.Protect == "NOACCESS" || region.Protect == "0x01") continue;
region.Entropy = CalculateRegionEntropy(hProcess, region.BaseAddress, region.Size);
allEntropies.Add(region.Entropy);
if (region.Entropy > HighEntropyThreshold)
{
result.HighEntropyRegions++;
result.HighEntropyTotalSize += region.Size;
}
}
if (allEntropies.Count > 0)
{
result.AvgEntropy = allEntropies.Average();
result.MaxEntropy = allEntropies.Max();
result.EntropyStdDev = CalculateStdDev(allEntropies, result.AvgEntropy);
}
return result;
}
/// <summary>
/// 快速估算内存区域熵值(单采样点,用于快速扫描模式)
/// </summary>
public double QuickEntropyEstimate(IntPtr hProcess, ulong baseAddress, ulong regionSize)
{
// 只采样区域中间的 256 字节
var sampleSize = 256u;
var offset = regionSize / 2;
if (offset + sampleSize > regionSize) offset = 0;
var buffer = new byte[sampleSize];
if (ReadProcessMemory(hProcess, (IntPtr)(baseAddress + offset), buffer, (int)Math.Min(sampleSize, regionSize), out _))
{
return CalculateShannonEntropy(buffer);
}
return 0;
}
/// <summary>
/// Shannon 熵计算
/// </summary>
public static double CalculateShannonEntropy(byte[] data)
{
if (data == null || data.Length == 0) return 0;
var counts = new int[256];
foreach (var b in data)
counts[b]++;
double entropy = 0;
double len = data.Length;
for (int i = 0; i < 256; i++)
{
if (counts[i] == 0) continue;
var p = counts[i] / len;
entropy -= p * Math.Log2(p);
}
return entropy; // 范围 [0, 8]
}
private static double CalculateStdDev(List<double> values, double mean)
{
if (values.Count <= 1) return 0;
var sumSq = values.Sum(v => Math.Pow(v - mean, 2));
return Math.Sqrt(sumSq / (values.Count - 1));
}
[DllImport("kernel32.dll", SetLastError = true)]
private static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress,
byte[] lpBuffer, int dwSize, out IntPtr lpNumberOfBytesRead);
}
/// <summary>
/// 熵分析结果
/// </summary>
public class EntropyResult
{
public double AvgEntropy { get; set; }
public double MaxEntropy { get; set; }
public double EntropyStdDev { get; set; }
public int HighEntropyRegions { get; set; }
public ulong HighEntropyTotalSize { get; set; }
}