stein-exe/DevMystical-deobf
GitHub: stein-exe/DevMystical-deobf
一款基于 Python AST 的源码混淆与解混淆工具,支持将 Python 代码进行多层加密混淆并安全地静态还原原始逻辑。
Stars: 0 | Forks: 0
[](https://www.python.org/)
[](LICENSE)
[](https://github.com/stein-exe/DevMystical-deobf/commits)
[](https://github.com/stein-exe/DevMystical-deobf)
[](https://github.com/stein-exe/DevMystical-deobf/stargazers)
[](https://github.com/stein-exe/DevMystical-deobf/network/members)
[](https://github.com/stein-exe/DevMystical-deobf)
### ◆ AST 级别的 Python 混淆 — 内置沙箱加固的解混淆器
*最初由 [DevMystical](https://github.com/DevMystical/Obfuscator) 开发 · 由 [Stein](https://github.com/stein-exe) 维护*
## ⟡ 概览
| ◈ | 详情 |
|---|---|
| 🐍 **语言** | Python 3.9+ |
| 📦 **依赖** | 无 — 仅使用标准库 |
| 🔒 **解混淆模型** | 静态分析 · 沙箱隔离的 exec · 仅限 AST 的反序列化 |
| 🎯 **混淆目标** | 任何有效的 Python 源文件 |
| 📁 **核心文件** | `obf.py` · `deobf.py` |
| ⚠️ **使用场景** | 教育 · 授权的代码分析 · CTF · 研究 |
## ▸ 快速开始
```
# 克隆
git clone https://github.com/stein-exe/DevMystical-deobf.git
cd DevMystical-deobf
# 混淆 — 无需安装,纯 stdlib
python obf.py
# 输入文件路径: myscript.py
# 输出写入至: a.py
# 反向去混淆
python deobf.py
# 输入文件路径 (输入 99 退出): a.py
# 成功!已保存至: a_deobf.py
```
## ✦ 项目结构
```
DevMystical-deobf/
├── obf.py ← obfuscation engine — AST → pickle → lambda chain
├── deobf.py ← deobfuscator — static reconstruction, sandbox-hardened
├── README.md
└── LICENSE ← MIT
```
## ◆ 功能
### 「 混淆器 」
| ✦ | 技术 |
|---|---|
| **AST 序列化** | 每个节点都使用 ISO-8859-1 编码单独进行 pickle 操作 |
| **Lambda/类型类链** | 匿名类层次结构 — 所有名称都被替换为 `_`, `__`, `___` 序列 |
| **素因数分解编码** | 整数表示为数学恒等式链 — 没有任何数字常量保留下来 |
| **嵌套字符树** | 每个字节都存储在混淆的属性链中 — 没有可见的字符串常量 |
| **运行时重建** | AST 从 pickle 片段重建,并通过 `compile` + `exec` 运行 |
### 「 解混淆器 」
| ✦ | 保障 |
|---|---|
| **仅限静态分析** | payload **绝不执行** |
| **最小化沙箱** | `exec` 在严格的允许列表下运行 — `open`, `os`, `eval`, `import` 均不可用 |
| **`_AstOnlyUnpickler`** | 在 pickle 层阻止所有非 `ast.*` 类 |
| **`ast.Expr` 排除** | 最终的 `exec(…)` 调用在分析开始前被剔除 |
| **输出验证** | 在写入前使用 `ast.parse()` 重新解析结果 |
| **零依赖** | 纯 Python 标准库 |
## ⚡ 混淆的工作原理
五个堆叠的转换层,按顺序应用:
```
flowchart TD
A[Python source] --> B[AST Serialization\nEach node pickled individually\nISO-8859-1 encoding]
B --> C[Lambda / Type Class Chain\nlambda _: type(*_) hierarchy\nAll identifiers → underscore sequences]
C --> D[Number Encoding\nPrime factorization chains\nco_argcount-derived primitives]
D --> E[Character Storage\nEvery byte in nested class tree\nAccess via obfuscated attribute chains]
E --> F[Runtime Reconstruction\nAST rebuilt from pickle fragments\ncompile + exec]
F --> G[Obfuscated output runs\nas original code]
```
## 🛡️ 安全模型
解混淆器以 **静态** 方式重建源代码 — 它从不运行混淆后的 payload。三项明确的安全威胁缓解措施:
| ⚠️ 风险 | ✗ 未修补 | ✔ 已加固 |
|---|---|---|
| **分析时的恶意赋值** | 带有完整 `builtins` 的 `exec` — `open`, `os`, `eval`, `import` 均处于活跃状态 | 带有最小化允许列表的 `exec` — 仅限 `type`, `getattr`, `setattr`, `hasattr`, `isinstance`, `len` 和基本类型 |
| **Pickle 反序列化任意类** | 零限制的 `pickle.loads` | `_AstOnlyUnpickler` — 仅允许 `ast.*` 类通过;其他所有内容都会引发 `UnpicklingError` |
| **`exec(…)` 节点触发 payload** | `ast.Expr` 节点可能混入分析批次中 | `ast.Expr` 节点完全从执行批次中排除 |
## ▸ 用法
### 「 混淆器 」
**CLI**
```
python obf.py
# 输入文件路径: myscript.py
# 输出写入至: a.py
```
**Python API**
```
from obf import obfuscate
with open("myscript.py", "r", encoding="utf-8") as f:
source = f.read()
obfuscated = obfuscate(source)
with open("myscript_obf.py", "w", encoding="utf-8") as f:
f.write(obfuscated)
```
### 「 解混淆器 」
**CLI**
```
python deobf.py
# 输入文件路径 (输入 99 退出): a.py
# 正在处理: a.py ...
# 成功!已保存至: a_deobf.py
```
**Python API**
```
from deobf import deobfuscate_file, deobfuscate_source
# File API — 读取输入,写入 _deobf.py,返回输出路径
output_path = deobfuscate_file("a.py")
# String API — 直接传递 source,获取恢复的 source
with open("a.py", encoding="utf-8") as f:
source = f.read()
restored = deobfuscate_source(source)
```
## ⟡ 解混淆器的工作原理
```
flowchart TD
A[Obfuscated .py input] --> B[ast.parse\nStatic parse only — zero execution]
B --> C[Extract assignments\nexec in minimal sandbox\nno os / open / eval / import]
C --> D[Find pickle list\nLocates list of path + bytes pairs]
D --> E[_AstOnlyUnpickler\nRebuilds ast.* nodes\nBlocks ALL other classes → UnpicklingError]
E --> F[Reconstruct AST tree\nWalks path fragments\nSets nodes in reverse order]
F --> G[ast.unparse\nProduces clean Python source]
G --> H[ast.parse validation\nConfirms output is valid syntax]
H --> I[Write _deobf.py output]
```
## ⚠️ 局限性
| 🚧 | 详情 |
|---|---|
| **格式锁定** | 仅支持 DevMystical 混淆格式 — 不支持其他混淆器 |
| **无法恢复注释** | 输出为紧凑的 `ast.unparse` 风格 — 注释和原始格式不存储在 AST 中 |
| **输入损坏** | 如果混淆后的文件在混淆后被修改,可能会在 stderr 上输出警告并生成部分结果 |
## 🗺️ 路线图
| ◈ | 项目 |
|---|---|
| ☐ | **批处理模式** — 一次性混淆/解混淆整个目录 |
| ☐ | **格式化输出** — 自动对解混淆结果运行 `black` 或 `autopep8` |
| ☐ | **格式检测** — 自动检测混淆变体并路由到正确的解混淆器 |
| ☐ | **测试套件** — 基于属性的往返测试(混淆 → 解混淆 → 比较 AST) |
## ⟡ 需要更强的混淆?
如果您需要生产级别的 Python 混淆,请查看 [hermit](https://github.com/stein-exe/hermit/) — 一款由 [Stein](https://github.com/stein-exe) 构建的更高级的混淆器。
## 📄 许可证
基于 **MIT License** 发布。完整条款请参见 [`LICENSE`](LICENSE)。
*基于 Python 的 AST 构建 — 因为真正的混淆发生在语法树层面,而非表层。*
标签:DNS 反向解析, Python, 云安全监控, 代码反混淆, 代码安全, 代码混淆, 无后门, 漏洞枚举, 自动化payload嵌入, 静态分析