kapla0011/InsomniacUnwinding
GitHub: kapla0011/InsomniacUnwinding
一种改进型睡眠混淆技术,在加密 payload 内存的同时精确保留 UNWIND_INFO 结构,确保栈展开功能不受破坏。
Stars: 50 | Forks: 8
# InsomniacUnwinding
无需调用栈伪装的精确 UNWIND_INFO 保留睡眠混淆技术。
**博客文章:** [Unwind Data Can't Sleep - Introducing InsomniacUnwinding](https://lorenzomeacci.com/unwind-data-cant-sleep-introducing-insomniacunwinding)
## 概述
传统的睡眠混淆会加密整个 payload 镜像,从而破坏栈展开。此实现基于由 (@C5pider) 创建的 Ekzo,并精确地仅保留栈遍历所需的 UNWIND_INFO 结构(约 250 字节,而完整的 `.rdata` 约为 6KB)、PE 头以及 .pdata 节。
## 工作原理
定时器链被扩展,以便在加密后修补回保留的区域:
1. `VirtualProtect` → RW
2. `SystemFunction032` → 加密整个镜像
3. `RtlCopyMemory` → 恢复 PE 头
4. `RtlCopyMemory` → 恢复 .pdata
5. `RtlCopyMemory` × N → 恢复每个 UNWIND_INFO 区域
6. `WaitForSingleObject` → 睡眠
7. `SystemFunction032` → 解密
8. `RtlCopyMemory` → 恢复 PE 头(被异或为乱码)
9. `RtlCopyMemory` → 恢复 .pdata
10. `RtlCopyMemory` × N → 恢复每个 UNWIND_INFO 区域
11. `VirtualProtect` → RX
12. `SetEvent` → 发出完成信号
## 使用说明
1. 在 Visual Studio 中构建(x64 Release)
2. 运行:
```
.\InsomniacUnwinding.exe
```
3. 附加调试器并在睡眠期间检查主线程的调用栈。它应该能通过 `BaseThreadInitThunk` 和 `RtlUserThreadStart` 正确解析。
## YARA 测试
测试特征码嵌入在 `.rdata` 和 `.data` 中:
```
.\yara64.exe DeadBeefSignature.yar
```
预期结果:
- **唤醒状态:** 2 次命中
- **睡眠状态:** 0 次命中(两者均被加密,仅保留了 UNWIND_INFO)
## 核心见解
调用栈伪装是无内存文件支持的 sleepmask 的架构性后果,而非基本要求。当 sleepmask 从有内存文件支持的内存中执行时,伪装就变得不必要了。
## 致谢
感谢 Alex Reid (@Octoberfest73) 指出了初始研究中的一个错误,从而促成了这一改进的实现。
标签:C/C++, DNS 反向解析, OpenAI, PE文件, UML, 事务性I/O, 免杀技术, 内存规避, 客户端加密, 恶意载荷, 暴力破解检测, 端点可见性