# [种子] Unity IL2CPP 游戏逆向 → 还原元数据 + 修改逻辑

## 场景分类
游戏安全 / 移动逆向

## 目标概述
一个 Unity 打包的 Android 游戏（IL2CPP 模式），游戏内购或核心算法在 C# 编写但已编译成 native。需要还原方法名、定位关键逻辑、改动 / hook 实现修改。

## 完整执行链路

1. 拆包 APK，确认是 IL2CPP
   ```bash
   unzip target.apk -d apk
   ls apk/lib/arm64-v8a/        # 看到 libil2cpp.so 即 IL2CPP
   ls apk/assets/bin/Data/Managed/Metadata/
   # 关键文件: global-metadata.dat
   ```
2. 用 **Il2CppDumper** 还原元数据
   ```bash
   Il2CppDumper libil2cpp.so global-metadata.dat output/
   # 产物：DummyDll/ + script.json + il2cpp.h + dump.cs
   ```
3. 把 IDA 的 IL2CPP 脚本（`ida_with_struct.py`）跑一遍
   - 加载 libil2cpp.so → File → Script File → 选 ida_with_struct.py → 选 script.json
   - IDA 现在能看到 C# 方法名、签名、字符串
4. 在 dump.cs 里按业务关键字搜（`AddCoin` / `OnPurchase` / `Verify` / `IsVip` / `CheckSign`）
5. 拿到关键方法的偏移 → IDA 跳过去看反汇编 / 反编译
6. 选择修改方式：
   - **静态 patch**：直接 IDA 把判断改成 `mov w0, #1; ret`
   - **动态 hook**：Frida 接 il2cpp 方法（用 Frida-Il2CppBridge）
7. 重打包验证 / 注入验证

## 踩坑记录

| 问题 | 原因 | 解决方案 | 耗时 |
|------|------|---------|------|
| Il2CppDumper 报 metadata 版本不支持 | 新版 Unity 改了 metadata 格式 | 升级 Il2CppDumper 到最新 / 用 Il2CppInspectorRedux 替代 | 30min |
| global-metadata.dat 加密了 | 用了 AntiCheatToolkit / 自定义加密 | 找游戏初始化时的解密函数（通常在 il2cpp_init 周围）→ Frida 在 mmap 后 dump | 2h |
| dump.cs 看到方法名但 IDA 没匹配 | script.json 与 so 不一致 | 必须用同一次 dump 的产物；换 IDA 时清缓存 | 20min |
| Frida hook IL2CPP 方法报错 | IL2CPP 方法不是标准 Java/ObjC，要算 method offset | 用 frida-il2cpp-bridge 库，不要硬写 Interceptor.attach | 1h |
| Patch 后游戏闪退 | 校验文件 hash 或 anti-tamper | 找 hash 校验逻辑也 patch 掉，或用 hook 不改文件 | 2h |
| 重打包后启动崩溃 | apksigner v2 签名不能改字节后再签 | 删 META-INF + apktool b + apksigner sign 一气 | 30min |

## 工具链发现

- **Il2CppDumper** 老牌但仍是默认选择
- **Il2CppInspectorRedux** 更现代，支持新 Unity，能输出 IDA / Ghidra / Binary Ninja 多种插件脚本
- **frida-il2cpp-bridge** 是 IL2CPP 上 hook 的事实标准，比裸 Frida 强 N 倍
- **DnSpy** / **dnSpyEx** 用于看 DummyDll（dump 出来的伪 .NET assembly）
- **UnityCheat** 系列辅助工具（GameGuardian 系不展开）

## 关键代码/命令

frida-il2cpp-bridge hook 示例：

```typescript
// hook.ts
import "frida-il2cpp-bridge";

Il2Cpp.perform(() => {
    const Assembly = Il2Cpp.domain.assembly("Assembly-CSharp").image;

    // hook static method
    const PlayerData = Assembly.class("PlayerData");
    PlayerData.method("AddCoin").implementation = function (n: number) {
        console.log("[+] AddCoin called with:", n);
        return this.method("AddCoin").invoke(99999); // 改成 99999
    };

    // hook instance method
    const Purchase = Assembly.class("Purchase");
    Purchase.method("VerifyReceipt").implementation = function () {
        console.log("[+] VerifyReceipt → always true");
        return true;
    };
});
```

```bash
# 编译 + 注入
npm install frida-il2cpp-bridge
frida-compile hook.ts -o hook.js
frida -U -f com.target.game -l hook.js --no-pause
```

IDA 静态 patch：

```text
1. 打开 libil2cpp.so，跑 il2cpp_load_metadata.py
2. 跳到 dump.cs 中 IsPurchaseValid 对应的偏移
3. 函数开头改成 MOV W0, #1; RET（ARM64）
4. Apply Patches → Save → 替换回 APK → 重签名
```

## 对本包的改进建议

- `reverse-engineering/SKILL.md` 已覆盖 Unity，但缺 IL2CPP **完整工作链** 案例
- `reverse-engineering/references/il2cpp-cheatsheet.md` 单独成文：dump 工具对比、frida-bridge 模板、加密 metadata 处理
- bootstrap manifest 增加 frida-il2cpp-bridge

## 可复用的模式/脚本片段

**IL2CPP 标准流程**：

```text
1. 确认 IL2CPP（看 lib/abi 下有无 libil2cpp.so）
2. 找到 metadata（assets/bin/Data/Managed/Metadata/global-metadata.dat 或被加密）
3. Il2CppDumper / Inspector 还原
4. IDA + 脚本带回元信息
5. dump.cs 搜业务关键词
6. 选择 patch 还是 hook
7. 验证（启动 + 实际场景）
```

**加密 metadata 处理**：

```text
1. Frida 在 fopen/open 系调用上挂钩，看谁读 global-metadata.dat
2. 在 mmap/read 后 dump 内存里已解密的元数据
3. 把 dump 出来的内存当 metadata 喂给 Il2CppDumper
```

## 进化动作
- [ ] reverse-engineering/references 增加 il2cpp 完整章节
- [ ] bootstrap-manifest 加入 frida-il2cpp-bridge / Il2CppInspectorRedux
- [x] 路由矩阵已含 Unity / IL2CPP

## 环境信息
- Windows / macOS（运行 Il2CppDumper 用），目标设备 Android arm64
- IDA Pro 7.7+ 或 Ghidra 11+
- frida-tools 16.x, frida-il2cpp-bridge 0.9+
- Unity 版本: 2019.x - 2022.x（不同版本 metadata 格式略异）

## 脱敏要求
本条目为种子数据，基于公开技术模式编写，不涉及任何真实游戏。包名 `com.target.game` 为占位符。
