news 2026/10/23 13:37:20

从熵值到 OEP:Decepticon Reverser 的加壳识别与脱壳实战手册

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
从熵值到 OEP:Decepticon Reverser 的加壳识别与脱壳实战手册

【免费下载链接】Decepticon

Autonomous Hacking Agent for Red Team

项目地址:https://gitcode.com/gh_mirrors/de/Decepticon
点击查看免费下载

本文以 Decepticon 逆向(Reverser)技能树中的packer-unpackingPlaybook 为主体,完整覆盖加壳二进制的识别(熵值分析 + 特征匹配)、自动脱壳(UPX/ASPack/MPRESS)、手动脱壳(Themida/VMProtect/Enigma)与反反脱壳对抗的全流程,并结合仓库源码解析 Decepticon 内置的bin_packer工具是如何把"熵值 + 签名"判定自动化落地的。读完后,你可以独立判断任意二进制是否被加壳、选择正确的脱壳路径,并知道如何把脱壳结果沉淀到 Decepticon 的知识图谱中。

1. Playbook 定位:Reverser 工作流中的脱壳环节

该 Playbook 位于 Decepticon 的标准逆向技能目录下,元数据声明其子域为reverse-engineering,并映射到 MITRE ATT&CK 的 T1027.002(Obfuscated Files or Information: Software Packing),触发词覆盖packer unpack upx aspack themida vmprotect mpress pecompact enigma unpacking(见 SKILL.md)。

在 Reverser 技能目录(reverser/SKILL.md)定义的标准工作流中,本 Playbook 处于"快速分诊 → 加壳判定 → 脱壳"的关键节点:

  1. bin_identify— 确认格式、架构、NX/PIE;
  2. bin_packer— 熵值 + 特征签名,判定是否加壳;
  3. 若判定为加壳 → 进入本 Playbook,脱壳后重新识别;
  4. 之后再做bin_strings、bin_symbols_report、版本串 CVE 关联等深度分析。

也就是说,脱壳质量直接决定后续所有静态分析的可靠性——壳未脱干净,字符串与符号分析全部失真。

2. 第一步:检测加壳(熵值 + 工具双轨)

2.1 整体熵值快速筛查

Playbook 给出的第一手手段是计算整个二进制的 Shannon 熵,熵 > 7.0 bits/byte 大概率意味着压缩或加密:

# Entropy quick-check (>7.0 across the binary = likely packed) ent /tmp/sample # or python3 -c " import sys, math d = open('/tmp/sample','rb').read() f = [0]*256 for b in d: f[b] += 1 h = -sum((c/len(d))*math.log2(c/len(d)) for c in f if c) print(f'entropy={h:.3f}') "

2.2 段级熵与工具化检测

整体熵正常但存在局部异常时,应下钻到段(section)级别,并用专门的检测器交叉验证:

# Section-level entropy via radare2 r2 -qc "iSj" /tmp/sample | jq '.[] | "\(.name): \(.entropy)"' # Tool-based detection detect-it-easy /tmp/sample # most reliable, GUI + CLI diec /tmp/sample # CLI for DIE yara -r /opt/yara-rules/packers/ /tmp/sample

Decepticon 内置的对应助手是一个 LangChain 工具调用:

bin_packer("/tmp/sample")

2.3 源码级实现:bin_packer的判定逻辑

bin_packer工具定义在 tools/reversing/tools.py,其核心委托给 packer.py 中的detect_packer。从源码结构看,判定逻辑分三层:

第一层:Shannon 熵计算。shannon_entropy用Counter统计字节频率后按标准公式累加,与 2.1 中 Python one-liner 的算法完全一致(packer.py)。

第二层:特征签名匹配。维护一张约 21 条魔数/段名签名的表,命中即给出具体壳名:

_SIGNATURES: list[tuple[bytes, str]] = [ (b"UPX!", "UPX"), (b"UPX0", "UPX"), (b"UPX1", "UPX"), (b"UPX2", "UPX"), (b".aspack", "ASPack"), (b".adata", "ASPack"), (b"PEBundle", "PEBundle"), (b".petite", "Petite"), (b".Themida", "Themida"), (b".vmp0", "VMProtect"), (b".vmp1", "VMProtect"), (b".enigma1", "Enigma Protector"), (b".enigma2", "Enigma Protector"), (b".MPRESS1", "MPRESS"), (b".MPRESS2", "MPRESS"), (b"ByDwing", "ASPack"), (b".mew", "MEW"), (b"NSPack", "NsPack"), (b"PECompact2", "PECompact"), (b"Y0da", "Yoda's Protector"), ]

第三层:综合裁决(PackerVerdict)。判据为entropy > 7.0 or 签名命中即标记likely_packed;并附两条诊断注释——熵 > 7.5 但无签名时提示"高度怀疑自定义壳"(custom packer),熵 < 4.0 时提示"低熵,可能未加壳或文本占比高"。返回给 Agent 的 JSON 结构为:

{ "likely_packed": true, "entropy": 7.842, "packer": "UPX", "signatures": ["UPX"], "notes": [] }

该判定行为由单测固化,例如用b"UPX!" + os.urandom(2048)验证 UPX 命中、用os.urandom(8192)验证"高熵无签名"分支(见 test_binary_strings_packer.py 中的TestPacker类)。

注意:bin_packer是启发式筛查器,不是最终裁定。Playbook 原文强调 detect-it-easy 等专用工具"most reliable",两者结论冲突时应以 DIE 的段级分析为准。

3. 常见壳的静态签名速查表

Playbook 给出的签名对照表(识别阶段的核心依据),完整保留如下:

PackerSignature
UPXUPX!magic at section header, sections namedUPX0,UPX1
ASPack.aspacksection, jump after entry to packed code
Themida.themidasection, anti-debug, anti-VM heavy
VMProtect.vmp0,.vmp1sections; obfuscated EP w/ virtualized handlers
MPRESS.MPRESS1,.MPRESS2sections
PECompactpec1section, encrypted sections
Enigma.enigma1,.enigma2sections
Petitesmall overlay,.petitesection
FSGtiny imports, packed sections
MEWMEWmagic in section name
Armadilloruntime decryption, anti-debug (older)

这张表与packer.py中的_SIGNATURES表高度呼应——自动化检测覆盖的是表中可魔数化的壳,而 Armadillo、FSG 这类依赖运行时行为的壳则需要结合 DIE/IDA 人工确认。

4. 自动化脱壳

4.1 UPX(最简单,优先尝试)

upx -d /tmp/sample -o /tmp/unpacked file /tmp/unpacked

若upx -d报 "not packed by UPX",通常是版本字段被篡改(反脱壳手法)。Playbook 给出的修复手段是把UPX!魔数后的版本字节补回0x0d再试:

# Patch the version byte back python3 -c " d = bytearray(open('/tmp/sample','rb').read()) # Find UPX! magic, fix version import re for m in re.finditer(b'UPX!', d): d[m.end()] = 0x0d # set version field open('/tmp/patched','wb').write(d) " upx -d /tmp/patched -o /tmp/unpacked

4.2 ASPack

unaspack /tmp/sample # or use ASPackDie / ASPack Stripper

手动路径:ASPack 的 OEP 跳板是 unpack stub 末端的JMP <reg>,在 x64dbg 下该点断点,随后用Scylla转储(仅 PE)。

4.3 MPRESS

quickunpack /tmp/sample # Or load in x64dbg, set BP on tail jump (E9 to OEP), dump w/ Scylla

4.4 PECompact / FSG

无可靠离线工具时,Playbook 给出两条路:使用unpacme(在 engagement 允许云端处理的前提下上传 UnpacMe 服务),或放进受监控沙箱走内存转储策略。注意云端上传受 engagement 授权约束,默认不应外传样本。

5. 手动脱壳:Themida / VMProtect / Enigma

这三类属于商业级壳,没有可靠的自动脱壳器,Playbook 按壳分别给出策略:

5.1 Themida

  1. 静态:识别 anti-debug 检查点,patch 或改写;
  2. 动态:x64dbg +ScyllaHide插件绕过 anti-debug;
  3. 对VirtualProtect下硬件断点(Themida 经由它解压);
  4. 命中后回溯查找已解密代码区;
  5. 到达 OEP 后用Scylladump;
  6. Themida 常为多层结构——每层重复上述过程。

5.2 VMProtect

VMProtect 把代码转译为自定义 VM 的字节码,没有意义简单的"unpack",只有三条现实路径:

  • 去虚拟化:提取 VM handlers + 编写翻译器。工具可选VTIL、vmpfix,或用 IDA + 字节码 trace 手工完成;
  • Trace + 符号执行:Triton或angr;
  • 放弃 RE,按黑盒处理:对接口做 fuzz。

针对 VMProtect 2 / VMP2 / CodeVirtualizer 的更系统工作流(VMEnter/VMEXIT 分类、VIP 追踪、handler 表恢复、报告形态),Decepticon 另设了专项技能 virtualized-protectors/SKILL.md,其核心原则是"避免脆弱的 VM handler 模式匹配,优先做控制流事实的渐进式恢复,不承诺自动去虚拟化"。

5.3 Enigma Protector

流程与 Themida 类似,ScyllaHide可处理多数检查;最难的是 license / 虚拟机层。按版本分:

  • v3–v5:可用Enigma Static Unpacker脚本化脱壳;
  • v6+:x64dbg + Scylla 手动处理,注意多次解密路径。

6. 通用手动脱壳技术(适用于任意壳)

Playbook 总结的六步通用手法,可作为任何无自动化工具时的默认流程:

  1. 视需要禁用 ASLR / DEP(ScyllaHide/setdllchar);
  2. 在入口点下断点;
  3. 单步穿过 unpack stub,关注三类信号:
    • 大块VirtualAlloc(解密区分配);
    • memset后紧跟解密代码写入;
    • 尾部 OEP 跳转(常见为JMP <reg>,或 PUSHAD/POPAD 后的RET);
  4. 疑似 OEP 处用Scylla(PE)或r2 -ddump 进程;
  5. 修复导入表(Scylla 可自动重建 IAT),保存 dump 出的 PE;
  6. 对 dump 文件重新走一遍静态分析(对应 Reverser 工作流中"unpack 后 re-identify"的要求)。

7. 反反脱壳对抗表

壳的 unpack stub 里通常内置检测逻辑,Playbook 给出了逐项对策:

Anti-unpackCounter
IsDebuggerPresentScyllaHide, or patch w/ NOP
NtQueryInformationProcess(ProcessDebugPort)ScyllaHide
Timing checks (rdtscmeasure)x64dbg "timing" plugin or patch
INT3 detection (BP byte scan)hardware BPs only
Self-checksumidentify check loop, patch comparison
TLS callbacks (run before main entry)BP in TLS callback list (IDA: View → Open Subviews → TLS)
Anti-VM (CPUID hypervisor bit)Run on bare metal or KVM w/ CPUID masking

其中 TLS 回调一项容易被漏掉:回调在main入口之前执行,anti-debug 逻辑若挂在 TLS 上,断点设在 EP 时检测早已跑完。

8. 脱壳结果的分级:Triage Gate 与典型样例

Playbook 把脱壳结果定性为"不是漏洞,而是分诊闸门",直接影响 engagement 的分析路线选择:

OutcomeImplication for engagement
Automated unpack succeeded → static analysis viableNormal triage path
Only partial unpack (multi-layer)Use dynamic analysis as primary
VMProtect / Themida heavyLikely commercial protection — escalate effort, schedule realistically
Cannot unpackBlack-box fuzz + dynamic only; document static-blind constraint

Playbook 同时列出了该判定的已知典型样例,可作为经验参照:

  • Stuxnet:多层加壳(含自定义例程);
  • WannaCry:UPX + 自定义混淆;
  • 大多数 commodity malware:UPX(免费 + 易用);
  • 网银木马:常见 Themida 或 VMProtect;
  • Cobalt Strike beacons:加密 shellcode + 反射加载器,"类壳"形态。

9. 结果回写:Promote 到知识图谱

Playbook 的收尾步骤是把结论沉淀到 engagement 知识图谱,保证跨迭代可查询:

kg_add_node(kind="observation", label="packed: <packer-name>", props={"sample":"<sha256>","entropy":<float>,"packer":"<name>"}) kg_add_edge(src=<sample>, dst=<observation>, kind="exhibits") # After unpack, re-run triage on the dumped file kg_add_node(kind="artifact", label="unpacked: <sha256>", props={"original":"<orig-sha256>","unpacker":"<tool>"})

对应的图谱工具实现在 research/tools.py:kg_add_node通过props里的确定性key做去重,kg_add_edge用带权有向边表达样本与观察之间的关系,且两者都会把非法 kind 枚举校验失败返回给调用方,因此实际调用时应以工具返回的合法 kind 列表为准。脱壳完成后,按 Reverser 工作流对 dump 文件重跑bin_identify/bin_strings/bin_packer闭环验证。

10. 适用前提与边界

  • 本 Playbook 的命令链(x64dbg、Scylla、ScyllaHide、ent、radare2、DIE、YARA)默认在受控的逆向沙箱/一次性 Windows 环境中执行;Decepticon 的 reverser 技能目录将其 scope 声明为isolated-lab,required_tools 为ghidra, radare2, sanitizer;
  • bin_packer只返回熵 + 魔数签名的启发式结论,对自定义壳、加密壳只能给出"高熵无签名"提示,最终定性仍需 DIE/IDA 人工确认;
  • 对 VMProtect/Themida,Playbook 明确不做"自动脱壳"承诺——现实产出是脱壳(去壳)与去虚拟化(devirtualization)两条不同成本曲线的路径选择,应按第 8 节的分诊表排期;
  • 涉及云端脱壳服务(如unpacme)的路径以 engagement 是否允许样本外发为前提,默认走本地沙箱 + 内存转储。

参考资料(仓库内)

  • packer-unpacking/SKILL.md — 本文主体 Playbook 原文
  • reverser/SKILL.md — Reverser 技能目录与标准工作流
  • virtualized-protectors/SKILL.md — VMProtect/VMP2/Themida 专项工作流
  • triage/SKILL.md — 脱壳前后衔接的快速分诊流程
  • tools/reversing/tools.py —bin_packer等逆向工具封装
  • tools/reversing/packer.py — 熵值与壳签名检测实现
  • test_binary_strings_packer.py — 检测逻辑的单测用例

【免费下载链接】Decepticon

Autonomous Hacking Agent for Red Team

项目地址:https://gitcode.com/gh_mirrors/de/Decepticon
点击查看免费下载

相关推荐

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/23 10:20:17

应急移动电源动态调度:配电网韧性恢复的MIP建模与Yalmip复现

简介&#xff1a;针对《Routing and Scheduling of Mobile Power Sources for Distribution System Resilience Enhancement》一文&#xff0c;这份资源提供了第二阶段MPS动态调度的MATLABYALMIP完整复现&#xff0c;面向从事配电网韧性提升、应急移动电源预配置与动态调度研究…

作者头像 李华
网站建设 2026/10/23 7:23:01

Co-IP实验中轻重链干扰的解决方案与优化策略

1. 实验背景与问题定位做Co-IP实验的同仁们应该都遇到过这样的场景&#xff1a;Western Blot结果中出现50kDa左右的异常条带&#xff0c;或是轻重链信号相互干扰导致目标蛋白条带难以分辨。这种情况在我们实验室每周至少出现3-5次&#xff0c;特别是当检测抗体与IP抗体的宿主物…

作者头像 李华
网站建设 2026/10/23 8:10:15

课堂行为检测数据集双格式解析与YOLO训练实战指南

简介&#xff1a;这是一份面向课堂场景的行为识别目标检测数据集&#xff0c;覆盖玩手机、阅读、写字、低头、睡觉、举手6类常见学生行为&#xff0c;可用于训练YOLO系列模型或进行课堂专注度分析实验。压缩包共2000个文件&#xff0c;以xml标注、txt标注及jpg图像三类文件为主…

作者头像 李华
网站建设 2026/10/22 7:21:54

kubeadm init 镜像拉取失败?修改 imageRepository 解决,不用改 tag

如果用kubeadm初始化一个K8s集群&#xff0c;最容易让人心态爆炸的步骤就是kubeadm init卡在 Pulling images 这一步。终端上几十个镜像名轮番显示Failed to pull image&#xff0c;重试一遍还是失败&#xff0c;最后只剩一个冷冰冰的[kubelet-check] It seems like the kubele…

作者头像 李华
网站建设 2026/10/19 14:33:16

XCharts:基于 UGUI 的纯代码绘制 Unity 数据可视化图表库

数据可视化图表库UI组件 【免费下载链接】XCharts A charting and data visualization library for Unity. Unity数据可视化图表插件。 项目地址&#xff1a; https://gitcode.com/gh_mirrors/xc/XCharts 点击查看 免费下载 本文以 XCharts 官方英文 README 为纲&#xff0c;…

作者头像 李华