xiaojianbang8888/OLLVM_Deobfuscator
GitHub: xiaojianbang8888/OLLVM_Deobfuscator
基于 Unicorn 模拟执行的 ARM64 ELF 共享库 OLLVM 通用反混淆工具,支持自动化还原多种控制流混淆。
Stars: 37 | Forks: 24
# OLLVM Universal Deobfuscator
通用 OLLVM 反混淆工具,基于 Unicorn 模拟执行,支持 ARM64 ELF 共享库的自动化混淆还原。
| | |
|------|------|
| 作者 | **小肩膀** |
| 微信 | xiaojianbang8888 |
| 官网 | https://xjbedu.site |
| B站 | https://space.bilibili.com/534838862 |
| 公众号 | 非攻code |
| 知识星球 | 小肩膀和他的朋友们 |
**平台定位:**
## 支持的混淆类型
| 混淆类型 | 说明 | 通用性 |
|---------|------|--------|
| 控制流平坦化 (CFF) | 状态机驱动的 dispatcher + 比较树 | ✓ 通用(含魔改变体) |
| 间接跳转 (BR) | 表驱动的计算跳转 | ✓ 通用 |
| 间接函数调用 (BLR) | 多层间接寻址的函数调用 | ✓ 通用 |
| 虚假控制流 (BCF) | 不透明谓词产生的虚假分支 | ✓ 通用 |
## 环境要求
- Python 3.8+
- capstone >= 5.0
- unicorn >= 2.0
- keystone-engine >= 0.9
pip install capstone unicorn keystone-engine
## 使用方法
### 基本用法
python ollvm_deobfuscator.py [-o output.so] [--type auto|cff|indirect]
### 参数说明
| 参数 | 说明 |
|------|------|
| `input` | 输入的 .so 文件路径 |
| `start` | 函数起始地址(十六进制) |
| `end` | 函数结束地址(十六进制) |
| `-o, --output` | 输出文件路径(默认:input.patched.so) |
| `--type` | 混淆类型:`auto`(自动检测)、`cff`、`indirect` |
### 使用示例
# CFF 还原(自动检测)
python ollvm_deobfuscator.py sample_cff.so 0x14400 0x14898
# 间接跳转还原
python ollvm_deobfuscator.py sample_indirect_br.so 0xd5cc 0xdbc8 --type indirect
# CFF + 虚假控制流还原
python ollvm_deobfuscator.py sample_bcf.so 0x19188 0x19c14
# 魔改OLLVM还原(64位状态变量)
python ollvm_deobfuscator.py sample_modified_ollvm.so 0xcc604 0xcd930
# 指定输出文件
python ollvm_deobfuscator.py input.so 0x1000 0x2000 -o output.so
# 处理同一SO中的多个函数
python ollvm_deobfuscator.py input.so 0x14400 0x14898 -o step1.so
python ollvm_deobfuscator.py step1.so 0x95c8 0xa960 -o step2.so
python ollvm_deobfuscator.py step2.so 0x13728 0x13a48 -o final.so
## 测试样本
| 样本文件 | 目标函数 | 地址范围 | 混淆类型 |
|---------|---------|---------|---------|
| sample_cff.so | .init_proc | 0x14400 - 0x14898 | 标准CFF |
| sample_indirect_br.so | JNI_OnLoad | 0xD5CC - 0xDBC8 | 间接跳转+间接调用 |
| sample_bcf.so | sub_19188 | 0x19188 - 0x19C14 | CFF + 虚假控制流 |
| sample_modified_ollvm.so | nSign | 0xCC604 - 0xCD930 | 魔改CFF(64位状态变量) |
## 如何确定函数地址范围
1. 用 IDA Pro 打开 .so 文件
2. 在 Exports 窗口找到目标函数
3. 函数起始地址:IDA 显示的函数头地址
4. 函数结束地址:RET 指令地址 + 4(或下一个函数的起始地址)
## 工作原理
### CFF 还原流程
基本块划分 → 找Dispatcher → 找状态寄存器 → 数据流分类真实块
→ Unicorn模拟恢复控制流 → 消除虚假分支 → Patch + NOP
### 间接跳转还原流程
扫描BR/BLR → 提取rebase常量 → 模拟常量区域
→ 对每个BR模拟读取目标 → 重定位表回退解析BLR → Patch
## 输出说明
[*] Input: sample_cff.so
[*] Range: 0x14400 - 0x14898
[*] Loaded ELF with 2 LOAD segments
[*] Extracted 51 basic blocks
[*] Detected obfuscation type: cff
[CFF] Dispatcher found at 0x144a0 (fan-in: 20)
[CFF] State register: w8
[CFF] Real blocks: 21, Dispatch blocks: 30
[CFF] Flow graph recovered: 21 nodes
[CFF] Applying patches...
0x14400 -> B 0x14580
0x14580 -> B 0x14848
...
[PATCH] Saved to sample_cff.patched.so (20 patches applied)
[*] Done!
## 验证结果
将 patched .so 文件拖入 IDA:
1. 按 `G` 跳转到目标函数地址
2. 按 `P` 重新识别函数(如需要)
3. 按 `F5` 查看反编译结果
4. 对比原始混淆版本,确认控制流清晰可读
## 还原效果
| 样本 | 还原前 | 还原后 |
|------|--------|--------|
| sample_cff.so | 状态机while循环嵌套,不可读 | 清晰的顺序+条件逻辑,21节点20 patches |
| sample_indirect_br.so | BR X12 无法跟踪 | 11 BR + 4 BLR 全部还原为直接跳转 |
| sample_bcf.so | 324行不透明谓词混淆 | 消除7个虚假分支,23 patches |
| sample_modified_ollvm.so | 64位状态变量+寄存器预加载 | 24节点完整还原,23 patches |
## 相关文章
- OLLVM还原(一):控制流平坦化还原
- OLLVM还原(二):间接跳转还原
- OLLVM还原(三):间接函数调用还原
- OLLVM还原(四):虚假控制流还原
- OLLVM还原(五):适配魔改OLLVM
## License
仅供学习研究使用。
## 联系作者
有问题或建议,欢迎通过以下方式联系:
- **微信**:xiaojianbang8888
- **官网**:https://xjbedu.site
- **B站**:https://space.bilibili.com/534838862
- **公众号**:非攻code
- **知识星球**:小肩膀和他的朋友们
标签:ARM64, OLLVM, Unicorn, 云资产清单, 代码还原, 逆向工具, 逆向工程