xkenzzo31/dofus-retro-deobfuscator

GitHub: xkenzzo31/dofus-retro-deobfuscator

针对 Dofus Retro 1.48 Electron 客户端的自动化反混淆流水线,实现 V8 8.7 字节码反编译与 obfuscator.io 代码还原。

Stars: 0 | Forks: 0

# 🔓 Dofus Retro 反混淆器 **针对 Dofus Retro 1.48 Electron 客户端的自动化反混淆流水线。** 下载、反汇编并反编译整个客户端 —— 从原始 V8 8.7 字节码到具有函数分类的结构化 JavaScript。完全反混淆渲染器进程。只需一条命令。 ## ⚡ 快速开始 ``` # 构建 Docker 镜像(首次约 30 分钟 — 从源码编译 V8 8.7) docker build --platform linux/amd64 -t dofus-deob . # 运行 pipeline — 输出到 ./output/ docker run --rm --platform linux/amd64 -v ./output:/output dofus-deob ``` 就是这样。所有内容都输出在 `./output/` 中。 ## 🏗️ 客户端架构 Dofus Retro 1.48 是一个基于 **Electron 11.5.0** 的桌面应用程序,具有多层架构: ``` ┌─────────────────────────────────────────────────────────────┐ │ 🧠 Main Process (main.jsc) │ │ ├── Shield security module (AES-256-CBC, fingerprint) │ │ ├── Zaap/Thrift RPC client │ │ ├── CryptoJS (121 functions) │ │ ├── systeminformation v5.16.6 (~1,200 functions) │ │ └── obfuscator.io wrappers (~6,800 functions) │ ├──────────────────────┬──────────────────────────────────────┤ │ 34 IPC channels │ │ ├──────────────────────┘ │ │ 🖥️ Renderer Process (D1ElectronLauncher.js) │ │ ├── 76 exports to Flash via ExternalInterface │ │ ├── Packet relay (game ↔ main process) │ │ ├── Discord RPC integration │ │ └── UI management (login dialog, game window) │ ├──────────────────────┬──────────────────────────────────────┤ │ ExternalInterface │ │ ├──────────────────────┘ │ │ 🎮 Flash SWF (loader.swf) │ │ ├── 4,258 ActionScript 2 scripts │ │ ├── Game rendering, combat, maps, inventory │ │ ├── Network packet construction │ │ └── 72+ client→server packet types │ └─────────────────────────────────────────────────────────────┘ │ │ TCP/TLS :443 ▼ Dofus Retro Servers ``` ### 📊 客户端技术栈 | 组件 | 版本 | 角色 | |:----------|:--------|:-----| | Electron | 11.5.0 | 桌面外壳 | | Node.js | 12.18.3 | 后端运行时 | | V8 | 8.7.220.31-electron.0 | JavaScript 引擎 | | Chromium | 87.0.4280.141 | 渲染器 | | bytenode | 1.3.7 | `.jsc` 字节码编译器 | | Flash (Pepper) | 内置 | 游戏渲染 (SWF) | ## 🎯 我们提取了什么 —— 实话实说 ### 反混淆目标与实际结果 | 目标 | 大小 | 保护方式 | 反混淆级别 | 你实际得到什么 | |:-------|:-----|:-----------|:----------:|:----------------------| | `D1ElectronLauncher.js` | 644 KB | obfuscator.io (RC4) | ✅ **完全清理** | 29 KB 可读代码 —— IPC 通道、Flash 导出、UI 逻辑 | | `main.jsc` | 12.7 MB | V8 字节码 + obfuscator.io | ⚠️ **已反编译,仍被混淆** | 8,611 个具有有效 JS 语法的函数,但包装器调用未解析 | | `loader.swf` | 3.3 MB | 十六进制混淆的类名 | ✅ **已反编译** | 4,258 个 AS2 脚本(通过 JPEXS,单独工具) | ### 🟢 真正有用的内容 **D1ElectronLauncher.js → D1EL_clean.js** —— 这是真正的胜利。644 KB 的混淆代码变成了 29 KB 干净、可读的 JavaScript。你可以看到每一个 IPC 通道,每一个 Flash ExternalInterface 导出,完整的数据包中继逻辑,Discord RPC 设置以及窗口管理。这是对渲染器进程完整、可读的逆向。 **字节码反汇编 (ignition_disasm.txt)** —— 115 MB 的原始 V8 Ignition 字节码,涵盖所有 8,611 个函数。可用于配合 Ghidra 或你自己的工具进行手动分析。 **函数分类 (index.json + 分类文件)** —— 每个函数都根据常量池字符串按域(crypto, network, auth, electron, game, zaap)进行了标记。分类边界是正确的 —— 你知道 *哪些* 函数处理加密,*哪些* 处理网络 —— 即使里面的代码仍然被混淆。 **字符串数组(8,676 条目)** —— 完整解码的 obfuscator.io 字符串表已被提取并提供。客户端使用的每个字符串都在里面。 ### 🔴 尚未反混淆的内容(诚实说明) **main.jsc 业务逻辑仍然被混淆。** `main.jsc` 的反编译输出包含: - **12,101 行** 带有未解析的 `_0x...()` 包装器调用 - **19,437 行** 带有不透明的 `ctx_N` 闭包引用 - “可读”版本仅比 webcrack 输出 **小 8 KB**(0.3% 的实际解析率) 根本原因:**79% 的函数(约 6,800 个)是 obfuscator.io 包装器函数**,它们通过闭包捕获的解码器引用来解析字符串。这些无法静态解析 —— 它们需要运行时闭包上下文。我们的运行时捕获(来自 76,947 次调用的 229 个索引)仅触及皮毛。 **分类文件(crypto.js, auth.js 等)在实践中是什么样子的:** ``` // What you might expect: var hash = CryptoJS.SHA256(packet + counter); var encrypted = CryptoJS.AES.encrypt(hash, key, { iv: iv }); // What you actually get: _0x2fc62a(865, ctx_334[_0x3a2a3a], 3043, ctx_334[_0x450905], ctx_334[_0x50a1b0]); _0x22a54d(ctx_334[_0x437fe0], 4963, 5075, ctx_334[_0x316c8d], 8193); ``` 结构是有效的 JS,分类是正确的,但语义内容仍然被埋没在包装器间接引用之下。你可以看到函数边界、参数数量、控制流 —— 但如果不做进一步工作,看不出代码实际做了什么。 ### 🧬 main.jsc 组成(8,611 个函数) ``` 79.0% ██████████████████████████████████████░░ obfuscator.io wrappers (~6,800) ← unresolved noise 14.0% ███████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ systeminformation (~1,200) ← fingerprinting lib 1.4% █░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ CryptoJS (121) ← AES, SHA, HMAC 1.0% █░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ Shield business logic (~90) ← the real target 0.4% ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ Electron lifecycle (33) 0.2% ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ Network/socket (18) 4.0% ██░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ Other/uncategorized (~350) ``` ### 📂 分类文件 反编译器自动对函数进行分类并导出特定领域的文件: | 分类 | 文件 | 函数 | 内容质量 | |:---------|:-----|----------:|:----------------| | 🔐 Crypto | `crypto.js` | ~121 | 结构可见,CryptoJS 函数名保留(例如 `_doReset`, `_doProcessBlock`)。包装器调用未解析。 | | 🌐 Network | `network.js` | ~18 | 函数边界清晰。字符串引用仍被包装。 | | 🔑 Auth | `auth.js` | ~30 | 分类正确。代码语义被混淆。 | | ⚡ Electron | `electron.js` | ~33 | 一些可读字符串(`"app"`, `"BrowserWindow"`)。优于平均水平。 | | 🎮 Game | `game.js` | ~15 | 代码极少,严重包装。 | | 📡 Zaap | `zaap.js` | ~25 | Thrift RPC 结构可见。字符串引用被包装。 | ## 🔬 流水线步骤 | 步骤 | 内容 | 工具 | 输出 | |:----:|:-----|:-----|:-------| | 1️⃣ | 从 Cytrus CDN 下载 `main.jsc` + `D1ElectronLauncher.js` | Node.js | 原始客户端文件 | | 2️⃣ | 反汇编 V8 8.7 Ignition 字节码 | `v8dasm` (自定义修补版) | ~115 MB 反汇编代码 | | 3️⃣ | 将字节码反编译为 JavaScript(8,611 个函数) | `v8decompiler.py` | 13 MB 反编译 JS | | 4️⃣ | 后处理:语法修复、Babel 验证、webcrack | Python + Node.js | 2.3 MB 已验证 JS(84% 通过率) | | 5️⃣ | 反混淆 D1ElectronLauncher.js | webcrack | ✅ 29 KB 干净、可读的代码 | | 6️⃣ | 注释 + 分类函数,尝试字符串解析 | `resolve-strings.py` | 分类标签 + 最小字符串解析 | | 7️⃣ | 将所有内容打包为版本化 ZIP | zip | 可发布归档 | ### 📦 输出结构 ``` output/ ├── raw/ │ ├── main.jsc # 12.7 MB — Original V8 bytecode │ └── D1ElectronLauncher.js # 644 KB — Original launcher (obfuscated) ├── jsc_decompiled/ │ ├── ignition_disasm.txt # 115 MB — Raw V8 disassembly (useful for Ghidra) │ └── v2/ │ ├── decompiled.js # 13 MB — Full decompiled JavaScript │ ├── decompiled_valid.js # 2.3 MB — Babel-validated (84% of functions) │ ├── decompiled_webcrack.js # 2.3 MB — After webcrack pass │ ├── decompiled_readable.js # 2.3 MB — Final annotated version │ ├── index.json # 788 KB — Function index with categories │ ├── crypto.js # Extracted: crypto functions (CryptoJS) │ ├── network.js # Extracted: network/socket │ ├── auth.js # Extracted: authentication │ ├── electron.js # Extracted: Electron lifecycle │ ├── game.js # Extracted: game logic │ └── zaap.js # Extracted: Zaap/Thrift RPC ├── webcrack_d1el/ │ └── D1EL_clean.js # 29 KB — ✅ Fully deobfuscated launcher └── dofus-retro_VERSION_DATE.zip # Everything packaged ``` ## 🛡️ Shield 安全模块 —— 深入解析 Shield 是嵌入在 `main.jsc` 内部的反作弊/反机器人模块。这是通过反编译结构分析、运行时跟踪和手动重建相结合的方式逆向工程的 —— **并非**仅通过反编译代码完成。 ### API 接口(10 个方法) | 方法 | 用途 | 我们如何逆向它 | |:-------|:--------|:-------------------| | `init()` | 初始化 Shield,加载密钥 | 运行时跟踪 + IPC 通道分析 | | `getHash()` | 获取当前签名哈希 | D1EL IPC 处理程序分析 | | `getRandomNetworkKey()` | 生成 560 字符网络密钥 | 运行时捕获 + 密码学分析 | | `getSystemInformation()` | 收集硬件指纹 | systeminformation 库识别 | | `getTelemetry()` | 响应服务器遥测挑战 | 网络数据包分析 | | `applyPacketToSendPostProcessing()` | 签名传出数据包(4 步 AES) | 运行时跟踪 + 密码学重建 | | `onPacketSent()` | 发送后钩子(计数器增加) | D1EL IPC + 数据包分析 | | `onPacketReceived()` | 已接收数据包钩子 | D1EL IPC 分析 | | `parseBasicCryptedPacket()` | 解密传入的已签名数据包 | 密码学模式匹配 | | `cryptBasicPacket()` | 加密传出数据包体 | 运行时跟踪 | ### 🔐 数据包签名流程 ``` Input: raw_packet (string) Step 1: hash = SHA256(raw_packet + counter_string) Step 2: ct1 = AES_CBC_encrypt(hash, key=hash_array[k1], iv=static_iv) Step 3: ct2 = AES_CBC_encrypt(ct1, key=hash_array[k2], iv=static_iv) Step 4: iv_rand = randomBytes(16) ct3 = AES_CBC_encrypt(ct2, key=WRAP_KEY, iv=iv_rand) Output: raw_packet + "\xf9" + base64(iv_rand) + base64(ct3) + "\xf9" counter++ (5-digit zero-padded, must stay synced with server) ``` ### 🖥️ 硬件指纹识别 | 分类 | 数据点 | |:---------|:------------| | CPU | 型号、供应商、核心、线程、频率、标志、缓存、插槽 | | GPU | 型号、供应商、VRAM、驱动版本、分辨率 | | RAM | 插槽、大小、类型、速度、布局 | | Disk | 型号、序列号、大小、接口类型 | | Motherboard | 主板名称、供应商、BIOS 版本/日期、机箱类型 | | Network | MAC 地址、IP、网关、DNS、SSID | | System IDs | UUID、主板 UUID、DMI 标识符 | | VM detection | Docker 容器枚举、进程扫描 | ### 🚨 反作弊进程扫描 大约每 30 秒,Shield 会扫描: | 分类 | 检测到的工具 | |:---------|:---------------| | 🔍 调试器 | x64dbg, OllyDbg, WinDbg, gdb, lldb | | 🔧 逆向工程 | IDA Pro, Ghidra, Radare2, Binary Ninja | | 📡 网络嗅探器 | Wireshark, Fiddler, Charles Proxy, mitmproxy | | 🎯 内存编辑器 | Cheat Engine, ArtMoney, GameGuardian | | 🪝 插桩工具 | Frida, Xposed, Substrate | | 📊 进程监视器 | Process Explorer, Process Hacker, API Monitor | ## 🧩 混淆层 客户端使用带有 5 层保护的 [obfuscator.io](https://obfuscator.io/): | 层级 | 描述 | 状态 | 影响 | |:------|:------------|:------:|:-------| | 🔤 字符串数组 | 8,676 个字符串编码 + 旋转 | ✅ 已解析 | 数组已解码,但大多数调用点通过包装器 | | 🔀 包装器函数 | ~6,800 个通过闭包的间接层 | ❌ **未解析** | **这是主要阻碍。** 包装器使用需要运行时数据的闭包捕获解码器引用。捕获了 ~6,800 个中的 229 个。 | | 💀 死代码注入 | 带有 5 字符标签的不透明谓词 | ✅ 已移除 | 独立 eval 已剥离 | | 🌀 控制流平坦化 | Switch-dispatch 状态机 | ❌ 未反转 | webcrack 处理一些简单情况 | | 🔒 RC4 字符串编码 | 应用于 D1EL 启动器字符串 | ✅ 已解析 | 通过 webcrack | ### 为什么包装器是难题 ``` // The string array is decoded: ["addEventListener", "createElement", "appendChild", "prototype", ...] // 8,676 entries // Direct calls to the decoder ARE resolved: a0_0x2c3b(0x1a4) → "addEventListener" ✅ // But 99% of calls go through wrappers like this: function _0x3a2b1c(a, b, c, d, e) { return ctx_42(a, c - 113, d); // ctx_42 = closure-captured decoder } // ctx_42 is bound at runtime when the function is created inside a closure. // Without knowing what ctx_42 points to, we can't resolve the string. ``` 这就是为什么 `crypto.js` 包含 `_0x2fc62a(865, ctx_334[_0x3a2a3a], 3043, ...)` 而不是 `CryptoJS.AES.encrypt(...)`。 ## ⚙️ 它是如何工作的 ### V8 字节码反汇编 Dofus Retro 的 `main.jsc` 是一个 V8 8.7 编译的字节码缓存(由 [bytenode](https://github.com/nicedoc/bytenode) 生成)。没有现有工具支持 V8 8.7 反编译,所以我们构建了自己的: 1. 在 Docker 内部从源码编译 V8 8.7.220.31 2. 修补 `code-serializer.cc` —— 绕过版本、源码、标志和校验和检查(4 个补丁) 3. 在反序列化后注入字节码打印 4. 修补后的 V8 反序列化 `.jsc` 并转储每个函数的 Ignition 字节码 ### 自定义反编译器 (`v8decompiler.py`) 一个具有流式架构的完整 Ignition 字节码到 JavaScript 反编译器: ``` ignition_disasm.txt (115 MB) │ ▼ ┌─────────────┐ │ Parser │ Streaming: 1 function at a time (~50 MB peak RAM) └──────┬──────┘ ▼ ┌─────────────┐ │ CFG Builder │ Basic blocks, loop headers, try/catch regions └──────┬──────┘ ▼ ┌─────────────┐ │ SymExec │ Accumulator + register state → JS expressions └──────┬──────┘ ▼ ┌─────────────┐ │ Categorizer │ Tags: crypto, network, auth, electron, zaap, game └──────┬──────┘ ▼ decompiled.js + index.json + category files ``` **操作码覆盖:** 所有 155+ 个 V8 8.7 Ignition 操作码 —— 加载、存储、调用、跳转、闭包、生成器、异步、for-in/of、解构、展开、try/catch。 **Babel 验证:** 84% 通过率(7,238 / 8,611 个函数语法有效)。 ### Cytrus CDN 下载器 Ankama 通过 **Cytrus v6** 分发游戏文件,这是一个使用 FlatBuffers 清单的自定义 CDN: ``` 1. GET cytrus.cdn.ankama.com/cytrus.json → game versions 2. GET cytrus.cdn.ankama.com/{game}/.../manifest → FlatBuffers binary manifest 3. GET cytrus.cdn.ankama.com/{game}/bundles/{hash} → content-addressed bundles ``` 我们逆向工程了 FlatBuffers 清单模式(不存在公开文档),并编写了一个最小解析器,通过 SHA-1 验证从内容寻址的包块中重建文件。 ## 🛠️ 评估过的工具 | 工具 | V8 支持 | 结果 | 备注 | |:-----|:-----------|:------:|:------| | **v8dasm** | 任意(从源码编译) | ✅ 使用 | 我们流水线的 | | **webcrack** | JS 源码 | ✅ 使用 | 对 obfuscator.io 效果极佳 (D1EL) | | **JPEXS FFDec** | SWF/AS2 | ✅ 使用 | 用于 `loader.swf`(单独工具) | | **Ghidra** (自定义 SLEIGH) | V8 8.7 ✅ | ✅ 已构建 | 自定义处理器 —— 见下文 | | Ghidra_NodeJS (PositiveTechnologies) | V8 ≤ 8.6 | ❌ 失败 | 2021 年废弃,无 8.7 支持 | | View8 (suleram) | V8 ≥ 9.4 | ❌ 失败 | 对 8.7 来说太新 | | jsc2js (xqy2006) | 仅 V8 14.x | ❌ 失败 | 版本完全不对 | | jscdecompiler.com | Electron 17+ | ❌ 失败 | 对 Electron 11 来说太新 | | obfuscator-io-deobfuscator (ben-sb) | JS 源码 | ⚠️ 部分 | 对 D1EL 有效,在 13 MB 输出时崩溃 | ## 🔭 未探索的途径与未来潜力 主要的未解决问题是 **包装器解析** —— 那些使 `main.jsc` 输出不可读的约 6,800 个基于闭包的字符串解码器包装器。这些方法可以破解它: ### 🟢 高潜力 —— 将解锁可读的 main.jsc | 方法 | 它能解决什么 | 难度 | 当前状态 | |:---------|:--------------------|:----------:|:---------------| | **运行时 Electron 钩子** | 通过拦截实时闭包上下文解析所有 6,800 个包装器 | 🟡 中等 | Preloader 钩子存在,捕获了 229/6,800 个索引。需要 `DYLD_INSERT_LIBRARIES` 注入 —— 未发布。 | | **包装器符号执行** | 通过模拟闭包作用域链静态解析包装器 | 🔴 困难 | 每个包装器使用 `ctx_N` 引用捕获的解码器 + 参数转换。需要跟踪 8,611 个函数的作用域创建。 | | **Ghidra + 自定义 SLEIGH(完整分析)** | V8 字节码上的交叉引用、调用图、数据流 | 🟡 中等 | SLEIGH 处理器已构建(`V8:LE:32:8.7`),导入脚本存在。未自动化到流水线中。 | | **控制流去平坦化** | 从 switch-dispatch 恢复原始代码结构 | 🔴 困难 | 研究充分的问题,obfuscator.io 有边缘情况 | ### 🟡 中等潜力 | 方法 | 它能解锁什么 | 难度 | 备注 | |:---------|:---------------------|:----------:|:------| | **Ghidra P-code 反编译器** | Ghidra 在 V8 字节码上的原生反编译器 —— 可能更好地处理包装器 | 🔴 困难 | 需要将 155+ 个操作码映射到 P-code | | **Frida 插桩** | 钩住 V8 运行时以实时跟踪执行 | 🟡 中等 | 强大但 Shield 检测 Frida | | **差分分析** | 比较客户端版本间的字节码 | 🟢 简单 | 流水线版本已输出 —— 只需要差异工具 | | **SWF 协议提取** | 从 `loader.swf` AS2 自动提取数据包构建器 | 🟡 中等 | JPEXS 反编译它,映射到协议需要工作 | | **Unicorn Engine 模拟** | 在沙箱中模拟 V8 字节码以解析包装器 | 🔴 困难 | 避免运行真实客户端 | ### 🔵 研究方向 | 方法 | 备注 | |:---------|:------| | V8 快照差异分析 | 比较各版本的常量池 | | 基于机器学习的反混淆 | 在 229 个捕获的解码器映射上训练 | | Binary Ninja 插件 | Ghidra 的替代分析平台 | | 字节码变异测试 | 修补字节码,观察崩溃以发现活动代码 | ### 🔧 Ghidra 集成(已构建但未发布) 我们为 V8 8.7 分析构建了完整的 Ghidra 工具链: | 组件 | 用途 | |:----------|:--------| | `v8_87.slaspec` | V8 8.7 Ignition 的自定义 SLEIGH 处理器定义 | | `v8_87.ldefs` / `.pspec` / `.cspec` | 语言、处理器和调用约定定义 | | `ImportV8Binary.java` | 将解析的字节码导入 Ghidra 并带有命名函数 | | `annotate_v8_runtime.py` | 用符号名称注释运行时调用 | | `deobfuscate_string_array.py` | Ghidra 内的原位字符串数组解析 | | `deobfuscate_control_flow.py` | Ghidra 内的原位控制流反混淆 | ``` Workflow: 1. Import main.jsc with processor V8:LE:32:8.7 2. Run ImportV8Binary.java → 8,611 functions created with names 3. Run annotate_v8_runtime.py → runtime call annotations 4. Run deobfuscate_*.py → string/control flow deob passes 5. Use Ghidra's cross-references, call graphs, and data flow ``` ## 📈 结果摘要 | 指标 | 值 | |:-------|------:| | 反编译函数 | **8,611** | | Babel 有效函数 | **7,238** (84%) | | 处理的 Ignition 操作码 | **155+** | | D1EL 反混淆 | **644 KB → 29 KB** ✅ 完全可读 | | 字符串数组已解码 | **8,676 条目** | | 包装器调用已解析 (main.jsc) | **~229 / ~6,800** ⚠️ (3.4%) | | 运行时解码器调用已捕获 | **76,947** (229 个唯一索引) | | 已文档化的 Shield API 方法 | **10/10** | | 已文档化的 IPC 通道 | **34** | | 已文档化的 Flash 导出 | **76** | | 构建时间(首次运行) | **~30 分钟** (V8 编译) | ## 🔧 选项 ``` # 强制重新下载并重新处理 docker run --rm --platform linux/amd64 -v ./output:/output dofus-deob --force # 使用不同的 platform(darwin、linux、windows) docker run --rm --platform linux/amd64 -v ./output:/output dofus-deob --platform darwin # 跳过下载(使用现有的 raw 文件) docker run --rm --platform linux/amd64 -v ./output:/output dofus-deob --skip-download ``` ## 🏗️ 不使用 Docker 构建 如果你已经有为 V8 8.7 编译的 `v8dasm`: ``` npm install -g webcrack@2 export OUTPUT_DIR=./output ./scripts/deobfuscate.sh --platform darwin ``` ## 📁 项目结构 ``` ├── Dockerfile # Multi-stage build (V8 compiler + runtime) ├── DOCS.md # In-depth technical documentation ├── v8dasm/ │ ├── v8dasm.cc # V8 bytecode disassembler source │ └── patch_v8.py # 4 patches for V8 8.7 code-serializer.cc └── scripts/ ├── deobfuscate.sh # Pipeline orchestrator (7 steps) ├── v8decompiler.py # Ignition bytecode → JavaScript decompiler ├── clean-js.py # Babel validation + string array prelude ├── resolve-strings.py # String resolution + annotation + dead code removal └── download/ ├── cytrus.mjs # Cytrus v6 CDN API client ├── download.mjs # File reconstruction from CDN bundles └── manifest.mjs # FlatBuffers manifest parser (reverse-engineered) ``` ## ⚖️ 免责声明 本工具仅供**教育和研究目的**。旨在帮助理解基于 Electron 的游戏客户端底层工作原理。作者不认可或鼓励任何违反 Ankama 服务条款的行为。请负责任地使用。 ## 📄 许可证 MIT —— 见 [LICENSE](LICENSE) *由 Luska 构建 —— 研究于 2026 年进行*
标签:Docker 自动化, Dofus Retro, Electron 客户端, JavaScript 反编译, JSC 反汇编, MITM代理, Shield 安全模块, V8 字节码, 云资产清单, 代码分析, 凭证管理, 加解密分析, 去混淆工具, 游戏协议分析, 游戏安全, 网络安全, 请求拦截, 逆向工具, 逆向工程, 隐私保护