勒索软件检测需结合时间窗口、熵值突变与批量行为:每500ms统计目录下50个文件last_write_time突变且跨多子目录;读取文件头64KB与尾8KB计算局部熵值,双块熵>7.2且大小>4KB即高危;skip-step模式看加密/跳过段交替分布,fast模式看头部熵显著高于其余部分。

不能靠单次文件修改事件判断勒索软件,必须结合时间窗口、熵值突变和批量行为特征建模
用 std::filesystem::last_write_time 捕获高频写入时间戳
勒索软件不是逐个改文件,而是短时间(几秒内)批量触发大量文件的 last_write_time 更新。单纯监听“有文件被改”毫无意义,关键看密度:
- 每 500ms 统计一次当前目录下所有文件的修改时间,筛选出距当前时间
- 若单次统计中 > 50 个文件满足该条件,且这些文件分布在多个子目录(非单一临时目录),即触发可疑标记
- 避免误报:跳过
temp/、cache/、logs/等路径前缀,这些目录天然高频写入
用 std::vector<uint8_t></uint8_t> + std::accumulate 快速计算局部熵值
勒索软件加密后文件内容趋于随机,局部熵值会陡升。但全文件计算太慢,应只读取每个文件开头 64KB(含 PE/ELF 头)和结尾 8KB(常含加密填充):
- 使用
std::ifstream::read分块读取,避免seekg频繁跳转影响性能 - 对每块数据用
std::array<size_t></size_t>统计字节频次,再套用香农熵公式-sum(p * log2(p)) - 若某文件两块熵值均 > 7.2(接近完全随机的 8.0),且原始文件大小 > 4KB,列入高危队列
识别 skip-step 和 fast 加密模式的文件分布特征
现代勒索软件为提速,常采用间歇性加密策略。检测时不能只看“是否加密”,要看“怎么加密”:
立即学习“C++免费学习笔记(深入)”;
-
skip-step模式:检查同一目录下文件大小分布——若出现大量“加密段(如 1MB)+ 跳过段(如 3MB)”交替的连续文件(按文件名或创建时间排序),是强信号 -
fast模式:对比文件开头 1MB 和中间/结尾的熵值差异——若开头熵 > 7.0 而其余部分 - 注意绕过:某些变种会先创建空文件再写入,需同步监控
std::filesystem::file_size从 0→非0 的突变事件
绕过进程隐藏导致的监控失效:直接读取 NTFS $MFT 元数据
当勒索软件通过驱动级隐藏自身进程时,基于 EnumProcesses 或 WMI 的监控会漏掉源头。更可靠的方式是绕过 API,直接解析磁盘元数据:
- 以
FILE_SHARE_READ | FILE_SHARE_WRITE打开物理卷(如\\.\C:),用DeviceIoControl发送FSCTL_GET_NTFS_VOLUME_DATA - 定位 MFT 起始扇区,顺序读取
FILE_RECORD_SEGMENT_HEADER,提取每个文件的USN_JOURNAL_DATA中的时间戳与大小变更记录 - 该方式不依赖任何进程上下文,即使恶意软件已 hook
NtWriteFile,也无法干扰底层扇区读取
真正难的不是算熵或查时间戳,而是把这三类信号在内存中做实时关联:一个进程在 3 秒内触发了 200 次写操作,其中 87 个目标文件的头部熵值突增,且它们在磁盘上呈 skip-step 式物理簇分布——这时才值得杀进程并隔离卷。


















