antipaster/j2cc-deobfuscator
GitHub: antipaster/j2cc-deobfuscator
针对 j2cc 编译的 Java 原生二进制文件的静态去混淆工具,可解密字符串、移除反Hook检测并生成 IDA/Ghidra 分析脚本。
Stars: 0 | Forks: 0
# j2cc-deobf
针对 [j2cc](https://github.com/0x3C50/j2cc) 原生二进制文件的静态去混淆工具。该工具接收一个经过 j2cc 混淆的 DLL(或整个 JAR),并剥离保护层,以便你能在 IDA/Ghidra 中正常阅读它。

## 功能介绍
j2cc 将 Java 方法编译为原生代码,并将其打包到通过 JNI 在运行时加载的 DLL 中。在此基础上,它还添加了多层混淆:
- **字符串池加密 (String pool encryption)** — 所有字符串常量(类名、方法描述符等)都在 `.data` 节中使用 ChaCha20 进行了加密。如果不解密,你只能看到一堆原本应是字符串的乱码字节。
- **反 Hook 检查 (Anti-hook checks)** — 每个原生方法入口都会调用 `checkForHookedFunctions()`,该函数会遍历 JNI 函数表以查找挂钩。这对调试来说非常烦人。
- **控制流平坦化 (Control flow flattening)** — 基本块被打乱并通过一个带有 XOR 状态变量的分发器 switch 进行路由,将原本直观的代码变成了意大利面条式代码。
- **MethodHandle 间接调用** — 方法调用被封装在 `MethodHandle` invoke 中,从而隐藏了实际的调用目标。
本工具可以逆转所有这些混淆(或至少识别它们),让你能专注于实际逻辑。
## 构建说明
**环境要求:** 支持C++20的 MSVC (Visual Studio 2022+)。无外部依赖。
**Visual Studio:** 打开 `deobfuscator.slnx`,构建 x64 Release。
**命令行:** 在 `deobfuscator/deobfuscator/` 目录下运行 `build.bat`。你可能需要编辑文件顶部的 MSVC/SDK 路径以匹配你的安装路径。
### JAR 模式 vs 手动模式
如果你传入一个 `.jar` 文件,工具会自动从中提取 `j2cc/natives.bin` (DLL) 和 `j2cc/relocationInfo.dat` (ChaCha20 密钥)。这是最简单的方法。
如果你只有 DLL,可以将 `relocationInfo.dat` 作为第二个参数传入。如果你根本没有密钥文件,字符串解密将无法工作,但其他 Pass(反 Hook 移除、流平坦化检测等)仍会运行。
## 去混淆 Pass
工具按顺序执行以下 Pass:
1. **StringDecryption** — 在 `.data` 中找到加密的字符串池,使用来自 `relocationInfo.dat` 的 ChaCha20 密钥解密,并将明文写回二进制文件。此后,IDA 会自动检测 C 字符串。
2. **AntiHookRemoval** — 通过查找原生方法序言中调用最频繁的非导出函数来识别 `checkForHookedFunctions()`,然后将所有调用点 NOP 掉(每个 5 字节:`E8 xx xx xx xx` → `90 90 90 90 90`)。
3. **JNICallResolution** — 映射 `RegisterNatives` 调用,以找出哪些 Java 方法对应哪些原生函数地址。从 `initClass` 中提取类/方法/描述符三元组。
4. **MhCallRefResolution** — 检测基于 MethodHandle 的调用间接模式。
5. **FlowObfuscation** — 通过寻找特征性的 `XOR r/m32, imm32` 状态转换以及配套的 `CMP+JE` 分发器级联来检测控制流平坦化。报告受影响函数的分发器位置、case 数量和 XOR 密钥。
## 输出结果
控制台输出提供了完整的细分信息:PE 节、导出、Pass 结果、解密后的字符串(前 100 个)、按类分组的方法注册,以及显示字符串引用和调用目标的逐函数分析。
IDA/Ghidra 脚本会将所有原生函数重命名为其 Java 名称(例如,`sub_12345` → `j2cc_me_x150_j2cc_Main_main`),添加方法描述符注释,并标注池中的字符串引用。
## 限制
- 流平坦化会被检测并报告,但不会自动去混淆(你仍然需要手动逆向分析分发器,但至少你知道它在哪里以及 XOR 密钥是什么)。
- 字符串解密需要来自 `relocationInfo.dat` 的 ChaCha20 密钥。
标签:C++, ChaCha20, DLL分析, DNS 反向解析, GHAS, Ghidra, IDA, j2cc, Java安全, JNI, MSVC, Native二进制, 云安全监控, 云资产清单, 代码混淆, 去混淆, 反混淆工具, 字符串解密, 安全意识培训, 恶意代码分析, 控制流平坦化, 数据擦除, 逆向工程, 配置文件, 静态分析