thyrn90/eulogy
GitHub: thyrn90/eulogy
一款零依赖的 C++ x64 调用栈展开与运行时内存分析引擎,充当进程外微型调试器来精确重建目标线程的调用链。
Stars: 0 | Forks: 0
# 悼文 🪦
[]()
[]()
[]()
[]()
**零依赖 x64 调用栈展开器与微型调试器**
Eulogy 是一个进程外、纯 C++ 实现的执行引擎,旨在对运行中的 x64 线程进行深度的取证分析。它充当一个精准的微型调试器,能够冻结目标进程,并手动逆向数学栈操作(UWOP)以重建精确的调用链。
它不依赖庞大的第三方反汇编器(如 Capstone),也不进行具有侵入性的 DLL 注入。Eulogy 直接读取原始内存,解析 PE 异常目录(.pdata),处理复杂的编译器优化(链式展开),并输出在挂起时 CPU 正在执行的确切机器码字节。
## ⚙️ 武器库(核心功能)
* **零依赖十六进制转储:** Eulogy 直接从目标内存中提取并打印原始的 15 字节 x64 指令(OpCodes)。这绕过了加密/加壳程序,并在无需外部反汇编库的情况下提供即时上下文。
* **链式展开导航:** 经过高度优化的 C++ 库(如 ucrtbase.dll)会将其栈帧分割到多个表中。Eulogy 能够完美追踪 UNW_FLAG_CHAININFO 和 RBP(帧指针),从而在不崩溃的情况下导航这些复杂的 Microsoft CRT 瓶颈。
* **L1 栈缓存(零系统调用开销):** Eulogy 没有通过频繁的 Ring-3 到 Ring-0 上下文切换(ReadProcessMemory)来拖垮 CPU,而是实现了一种带有 Guard Page 回退机制的 4KB 批量读取缓存,直接从其自身本地内存中以闪电般的速度读取栈。
* **O(log n) 二分查找:** 可在毫秒级的时间内定位到 .pdata 目录中确切的 RUNTIME_FUNCTION 条目,避免了大型可执行文件上 O(n) 迭代带来的延迟。
* **严格的 RAII 与 ABI 对齐:** 构建时完全遵循 Windows x64 ABI。在 CPU 上下文中使用 alignas(16) 以防止隐蔽的 ERROR_NOACCESS API 失败,并严格管理线程句柄以防止僵尸锁。
## 📸 视觉证明(剖析)

## 🚀 快速入门(编译与使用)
Eulogy 不需要外部包管理器。它使用纯 Windows API。
1. 编译源码:
使用 MinGW / GCC(确保已启用 C++17 标准):
```
g++ -std=c++17 -O2 main.cpp -o eulogy.exe -ldbghelp
```
(注意:链接 dbghelp 仅仅是为了解析人类可读的符号名称,而不是用来执行实际的栈展开)。
2. 执行追踪:
找到目标进程的进程 ID(PID)并将其传递给 Eulogy。
```
./eulogy.exe
```
## 🧠 架构限制(权衡)
一款专业的工具会承认自身的边界。Eulogy 是为速度和隐蔽性而构建的,这不可避免地带来了一些架构上的权衡:
**头部覆写漏洞:** Eulogy 依赖 VirtualQueryEx 来定位 AllocationBase 并随后解析 DOS/NT 头(MZ/PE)。如果目标恶意软件使用了激进的反射式 DLL 注入,或者主动从内存中擦除其自身的头信息(Header Stomping),那么将无法定位 .pdata 目录。
**操作系统级死锁:** Eulogy 使用 SuspendThread 来捕获 CPU 上下文。如果目标线程在持有关键的操作系统锁(例如在 Windows 堆管理器内部)时被挂起,则可能会导致死锁。这是用户模式(Ring-3)调试中不可避免的现实情况。
**被剥离的符号:** 虽然 Eulogy 能够完美地计算出 RVA 并转储原始的 OpCodes,但如果目标没有配套的 PDB 文件,函数名(如 UnknownFunction)将无法被解析。
## ⚖️ 许可证
本项目基于 MIT 许可证授权 - 详见 LICENSE 文件。
标签:C++, Gophish, JARM, x64架构, 云资产清单, 内存分析, 底层开发, 数据擦除, 栈回溯, 端点可见性, 逆向工程