工具|Entropia——RustShellcode/BOF编译器"

admin 2026-10-18 21:27:47 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

cover_image

工具 | Entropia —— Rust Shellcode/BOF 编译器

原创

GLM-5.2
GLM-5.2

赛博生存指南

2026年6月29日 08:58
浙江

在小说阅读器读本章

去阅读

把 .etpy 源码一行命令编译成 Windows x64 shellcode 或 Cobalt Strike BOF,OPSEC 混淆全做成编译参数——这个叫 Entropia 的项目,代码到底写得怎么样?本文对它的 ~15800 行 Rust 做了一次完整审查。

仓库地址:https://github.com/entropykit/entropia

这是什么项目

Entropia 是一个实验性(pre-1.0)编译器,用 Rust 写成,把自创的 .etpy 语言编译成两种产物:

  • • Windows x86-64 位置无关 shellcode(.bin)
  • • Cobalt Strike Beacon Object File / COFF(.x64.o)

定位是红队 / 安全研究的 dual-use 工具(README 有明确的授权与责任使用声明,类比 nanodump、mimikatz 这类公开工具)。它最大的卖点是把传统\"C 编译器 + 链接器 + sRDI/Donut 位置无关变换 + 手工 OPSEC\"的多工具链,压成单个编译器,OPSEC 技术栈(指令多态、加密字符串、直接/间接系统调用、栈欺骗、sleep mask……)全部以 --opsec=... 编译参数的形式提供。

先看规模:

范围 行数
核心编译器 src/*.rs(17 个模块) ~11,000
工具链 tools/*(BOF 加载器、本地运行器、DAP 调试器、Win32 头生成器) ~4,800
合计 ~15,800 行 Rust

编译管线很清晰:

lexer → parser → AST 变换 → typecheck → dce → codegen → 输出
                                                  ↑
                                            OPSEC 多态后处理

下面进入正题:代码质量到底如何。


总体评价:7 / 10

一句话结论:

工程素养出色的实验性编译器。手写 x64 编码器和 COFF/Beacon 语义还原度令人印象深刻,错误诊断带稳定错误码,核心编译在简单程序下是正确的;但全仓库零单元测试、几处实质性 bug、以及一个有意保持宽松的类型系统,是它的主要短板。

它的问题不是\"写得很烂\",而是\"还没到 1.0 该有的工程纪律\"。

四个子领域的打分:

模块 评分 一句话
前端 lexer / parser 7.5 优先级阶梯扎实、诊断好;零测试、转义静默降级
语义分析 6.5 DCE/GC/PEB-walk 设计正确;类型检查实质宽松(部分有意)+ 一处真实空分支
后端 codegen / encoder / poly 7.0 encoder 编码质量高、reloc-aware;poly 指令边界隐患、str.format 溢出、COFF aux
工具链 8.0 分层清晰、Beacon/VEH 还原度高;coff.rs 缺边界检查、dap.rs 过大

先说亮点:这些地方写得确实好

1. x64 指令编码器质量很高

encoder.rs(1277 行)是整个项目正确性的命脉,它做对了几件手写编码器最容易翻车的事:

  • • rbp/r13 作基址寄存器时,mod=00 会被误解成 disp32,代码强制改成 mod=01 + disp8=0;
  • • rsp/r12(低 3 位是 100)在所有寻址模式下都正确补了 SIB 字节 0x24;
  • • spl/bpl/sil/dil 这类 8 位寄存器正确识别\"即使没有扩展寄存器也需要 REX 前缀\",避免了把 mov al,[mem] 误编码成 ah 的经典 bug;
  • • 立即数 size-aware:能塞进 imm8 就用 83 形式,否则才用 81,省字节。

更难得的是:整个后端没有 unsafe、没有 transmute,是纯 safe Rust。

2. 错误诊断有产品意识

类型检查器用了一套稳定的错误码体系 T001–T023,错误信息带行列定位,还常带可操作的修复建议(比如 \"Add an explicit cast (u32)arg\")。display_type 会把内部哨兵 ? 转成对用户友好的 <unknown>,不泄露实现细节——这是一个有人在认真做\"开发者体验\"的信号。

3. DCE / GC / PEB-walk 运行时设计正确

这几个最容易出隐蔽 bug 的地方,作者都做对了:

  • • \\DCE(死代码消除)\\正确保留了带 [Hook]/[Stage]/[Override] 属性的间接调用函数——这些函数没有被显式 call,但运行时会被入口 prologue 或钩子间接调起,漏保留就是\"链接期丢函数\"。作者没漏。
  • • 保守式 GC 的根扫描设计合理:入口处捕获 STACK_TOP、收集时保存全部 Win64 非易失寄存器、用\"本趟新增标记数为 0 才停\"的不动点算法处理多代引用链。
  • • PEB-walk 严格按 PE 导出目录的 Names → Ordinals → Functions 三级跳转解析 API,还专门处理了 ntdll 对栈对齐敏感(movaps)的坑。

4. OPSEC 多态变换是真的\"重定位感知\"

polymorphism.rs 在每个指令等价替换点都检查 overlaps_reloc 和 label_inside,避免改坏重定位字段。README 宣传的 \"reloc-aware\" 是有代码支撑的,不是营销话术。

5. 工具链分层复用做得干净

bof-loader 作为纯库被 CLI 运行器和 DAP 调试器共同依赖;Beacon API 的字节序 / 长度前缀与 Cobalt Strike 的 bof_pack 严格对称;DAP 的 readMemory 用 VirtualQuery 守卫避免野指针打爆调试器进程,反汇编视图还会叠加断点处的原始字节让你看到真实指令而非 0xCC——细节到位。


再说问题:按真实严重性分级

🔴 应该修的实质性 bug

1. 类型检查的一处\"空操作\"分支(typecheck.rs)

一个声明返回 int 但写了 ret;(不带返回值)的函数,会被静默放行。对应的 match 分支是空的,而隔壁 void 函数返回值却会报 T023 错误——这种不对称强烈暗示是写漏了一行 errs.push(...)。

2. str.format 的栈缓冲区溢出(codegen.rs)

字符串格式化用的是微软已废弃的 wsprintfA,搭配一个固定 256 字节、无边界检查的缓冲区。用户可控的格式串展开超长时,会越界写 .bss 段相邻 slot。一个安全工具里不该有的内存安全漏洞。

3. BOF 的 COFF 符号格式不规范(coff.rs)

输出的函数符号标了 IMAGE_SYM_DTYPE_FUNCTION(type=0x20)但 NumberOfAuxSymbols=0,不符合 COFF 规范的严格读法(正常要么 type=0x00,要么配 .bf/.ef 辅助记录)。宽松的 BOF loader 能吃,但严格的自研 loader 可能拒绝加载或偏移错位——这直接威胁\"BOF 能被加载\"这个核心卖点。

4. BOF 加载器解析外部 COFF 缺边界检查(tools/bof-loader/src/coff.rs)

解析 .obj 文件时,节表 / 符号表的访问没有边界校验直接切片 + .unwrap()。一个字段值被伪造的畸形 .obj,会让加载器在启动阶段直接 panic,而不是给出可读的错误信息。作为一个\"解析外部输入\"的入口,这里应当全部改成带校验的 ? 返回。

5. BeaconFormatFree 的 Vec 重建契约脆弱(tools/bof-loader/src/beacon.rs)

用 Vec::from_raw_parts(ptr, 0, cap) 重建并 drop 一个 Vec 来释放内存,依赖\"len 永远传 0\"这个隐式假设——一旦有人在 append 路径改用 Vec::push 或记录真实 len,就会以错误的 len/cap 释放导致未定义行为。用 dealloc + Layout 更稳。

6. 字符串转义静默降级(lexer.rs)

未知的转义符(比如 \\x、或者 Windows 路径 \"C:\\bad\" 里漏写的反斜杠)会被静默降级成字面字符,没有任何警告。在 BOF 场景里这是高频且极隐蔽的错误来源。

🟡 设计弱点 / 隐患

指令多态的扫描没有\"指令边界\"概念(polymorphism.rs)

这是审查里最技术性的一处隐患。多态变换是线性扫描字节流、按 i += consumed 前进的,没有维护\"指令起始偏移\"集合。这意味着当某条指令的立即数或位移字节,恰好拼出 REX.W + 0x85/0x09/0x21 + 合法 ModRM 的样子时,扫描器会误以为这是一条 test/or/and 指令并改写它——把指令内部字节改坏了。重定位检查防不住这种(位移字段不在 reloc 表里)。

需要说明:它不是\"随便一个程序就会崩\",触发需要特定的字节模式(立即数里恰好出现特定字节序列)。但它是一个真实的正确性隐患,且一旦触发极难调试。修法是让 codegen 在 emit 时记录每条指令的边界,多态扫描只在边界处尝试匹配。

try/catch 不支持嵌套

try/catch 的异常处理用了一组全局 BSS slot(__handler_pc/rsp/rbp),意味着嵌套 try 的内层会覆盖外层的 handler,内层退出后外层 raise 就丢了。这是 VEH-based 异常机制的固有局限,应当在文档里明示。

codegen 的栈对齐\"侥幸正确\"且无防护

Windows x64 ABI 要求调用瞬间栈 16 字节对齐。审查逐点复核后发现,目前多数调用点其实是对的——但全是靠\"恰好此刻 rsp 对齐\"侥幸成立,没有任何 assert 守护。任何对函数 prologue 的改动,都可能悄悄引入一个 8 字节错位、然后在某个深层调用处崩成无法追踪的 AV。建议加编译期栈深度跟踪或运行时断言。

C 头解析器与 README 承诺不符

cimport.rs 的顶层解析器拒绝函数声明、#include、#pragma、enum、非整数 #define——遇到就直接报错终止。但 README 的示例写着 use_c \"winuser.h\",暗示能直接喂 SDK 头。真实 SDK 头第一行就是 #include,会直接解析失败。实际上它只能消化由配套工具 entc-win32gen 从 win32metadata 生成的\"净化版\"头。这是文档与实现的落差,对用户是真实陷阱。

🟢 可维护性 / 小问题

  • • 类型系统刻意宽松:Cast 是\"逃生舱\"(任何 (T)expr 直接通过类型检查)、整数与指针双向自由互通。代码注释明确写着\"by design,未来会收紧\"。对写底层 shellcode 这种场景是合理的取舍——这不是 bug,是已知限制——但意味着类型检查对指针密集的代码基本不起作用,文档应该说清楚。
  • • 巨型文件:codegen.rs 3450 行(一个 struct 22 个字段)、dap.rs 1985 行(还内嵌了一个手写的表达式求值器),都到了该拆分的体量。
  • • 零散的 .unwrap() / unreachable!() 散落各处;内联汇编立即数的 hex/dec 转换里有一处\"注释和实现恰好相反\"的小矛盾。

最大的系统性短板:全仓库零单元测试

四个子审查一致确认:

src/*.rs 和 tools/*/src/*.rs 里没有任何 #[test],仓库也没有 tests/ 目录。 README 自己也写着 \"Tests: To be implemented\"。仅有 entc-debug/scripts/ 下 3 个 Python 冒烟测试。

对一个把源码编译成机器码的编译器来说,这是最要命的:

  • • 运算符优先级表、x64 指令编码、类型兼容规则、COFF 二进制格式、多态等价变换——全部没有回归网;
  • • 任何重构都只能靠人肉跑 examples 验证,风险极高;
  • • 而像类型兼容 compat、类型推断 infer_type、C 头解析 parse_header、COFF 解析 ParsedCoff 这些,全是纯函数,加测试的成本极低、收益却最高。

这是 ROI(投入产出比)最高的改进方向,没有之一。


如果要改进,优先级建议

  1. 1. 补单元测试(最高 ROI)——先覆盖 lexer 词法、parser 优先级阶梯、typecheck 的兼容性判断、C 头解析、COFF 解析(喂一个小 .obj fixture)。
  2. 2. 修掉上面 6 个 🔴 实质 bug——尤其 str.format 缓冲区溢出、类型检查空分支、BOF 加载器的 COFF 边界检查。
  3. 3. 给多态变换加指令边界跟踪,给 codegen 加栈对齐 assert——消除两类最隐蔽的崩溃源。
  4. 4. 拆分 codegen.rs / dap.rs 两个巨型文件。
  5. 5. 对齐 C 头解析器与文档——要么容错跳过函数声明 / #include,要么 README 明示只支持净化头。

写在最后

审完整体感受是:这代码不是 AI 粗制滥造的产物,也不是新手练手作。 指令编码器、错误码体系、保守式 GC、PEB-walk 运行时——这些地方都见得到真实的工程功底和踩坑经验(注释里能看到\"作者实际遇到过这个 AV 并修复了\"的痕迹)。

它的核心编译能力在简单程序下是正确的,OPSEC 栈的设计也是认真的。

它的问题,本质上是一个实验性项目还没补上 1.0 该有的工程纪律:

  • • 没有测试网,所以每次改动都在裸奔;
  • • 几处边界 bug 没补(尤其那个 str.format 溢出,在安全工具里特别讽刺);
  • • 类型系统还停在\"渐进收紧\"的早期阶段;
  • • 文档在某些地方(C 头支持)领先于实现。

以 experimental(实验性)的标准衡量,它是合格偏上的;但如果想正式宣称 \"Stable\",至少需要:补测试 + 修掉 🔴 列表 + 加固多态与栈对齐。

对于正在学编译器、学 Rust、或对红队工具链内部实现好奇的读者,这是一个相当值得读的代码库——编码器和运行时部分尤其有学习价值。


本次为只读审查,未修改任何源码。评估基于当前 main 分支快照,项目仍在活跃开发中,部分问题可能在后续提交中已修复。


工具|Entropia——RustShellcode/BOF编译器" 网络安全文章

工具|Entropia——RustShellcode/BOF编译器"

Entropia是一个用Rust编写的实验性编译器,可将.etpy语言编译为Windowsx64位置无关shellcode和CobaltStrikeBOF。项目约15800行代码,具备OPSEC混淆功能,审查发现其x64指令编码器质量高、错误诊断体系完善,但存在全仓库零单元测试、str.format缓冲区溢出等6个实质性bug。总体评价为工程素养出色但未达到1.0版本应有的工程纪律,建议优先补充测试和修复关键漏洞。
马斯克:Grok4.5性能或超Opus;Fable5将于本周解禁;福特CEO承认:根本赢不了比亚迪|极客早知道" 网络安全文章

马斯克:Grok4.5性能或超Opus;Fable5将于本周解禁;福特CEO承认:根本赢不了比亚迪|极客早知道"

文档涵盖了人工智能、汽车、科技产品及社会热点等多领域资讯。其中包括马斯克宣布旗下大语言模型Grok4.5开启内部测试,性能或超竞品;百度旗下昆仑芯计划在香港IPO;福特CEO承认在电动汽车竞争中不敌比亚迪;此外,还有谷歌限制Meta使用其AI模型、苹果或因AI时代成本上涨而为产品涨价等消息。同时也包含了新款东风猛士M817SUV上市以及三星GalaxyS27系列手机芯片信息等科技新品动态。
AI+Kuikly:7.5小时落地三端「多模态聊天App」实战" 网络安全文章

AI+Kuikly:7.5小时落地三端「多模态聊天App」实战"

本文记录了使用腾讯开源框架Kuikly结合AI在7.5小时内开发三端多模态聊天App的实战过程。通过28轮对话生成3500行代码,实现文本/图片消息发送、拍照识图、流式Markdown回复、SSE长连接、本地会话管理等核心功能。AI借助KuiklySkills和Rules精准选择组件库、扩展原生模块、自主定位Bug,相比传统开发节省90%时间,验证了AI+跨端框架的高效协同模式。
评论:0   参与:  0