NX-developer/stickwar-legacy-mod

GitHub: NX-developer/stickwar-legacy-mod

一个教育用途的原生 IL2CPP 安卓游戏逆向工程学习项目,演示了库注入、运行时函数 hook 和静态字段修补的完整技术链路。

Stars: 0 | Forks: 0

# Stick War: Legacy — 原生 IL2CPP Mod(教育用途) 一个开源的、原生的**作弊/修改器**,适用于离线单人 Unity **IL2CPP** 安卓游戏 *Stick War: Legacy*,本项目作为**逆向工程 学习项目**构建。它完整展示了如何将一个小型的原生库 **注入到 IL2CPP 游戏中**,如何**在运行时 hook 引擎函数**, 以及如何通过一个纯文本文件**切换所有功能** —— 无需 root,无需 Xposed,也无需独立的应用。 ## ✨ 功能 所有功能均**仅限玩家端**(敌方 AI 不受影响),并且可以通过配置文件实时开启/关闭。 | 功能 | 配置键 | 描述 | |--------|------------|-------------| | 💎 无限宝石 | `gems` | 高级货币读取为 100,000,000 | | 🪙 无限金币 | `gold` | **你方**队伍的战斗内金币 | | 👥 无单位上限 | `unlimited_army` | 移除**你方**队伍的人口上限 | | 💥 一击必杀 | `one_hit_kill` | 你的单位单次攻击即可摧毁敌人 | | 🛡️ 无敌模式 | `god_mode` | 你的单位不会受到任何伤害 | | ⬆️ 无限升级点数 | `unlimited_upgrades` | 军械库升级点数保持最大值 | 配置文件(首次启动时自动创建): ``` /storage/emulated/0/Android/data/com.maxgames.stickwarlegacy/files/StickWarCheats.txt ``` ``` # 1 = 开启,0 = 关闭。保存的更改将在约 1 秒内生效(无需重启)。 gems=1 gold=1 unlimited_army=1 one_hit_kill=1 god_mode=1 unlimited_upgrades=1 ``` ## 🧠 工作原理 这整个项目就是一个微小的原生库(`libcheat.so`,约 20 KB),旨在 **游戏自身的进程内**加载。 ### 1. 注入 — `patchelf --add-needed` IL2CPP 游戏将其所有的 C# 逻辑运行在 `libil2cpp.so` 中。我们不使用 单独的 loader 应用,而是将我们的库添加为游戏自身的 `libil2cpp.so` 的 **直接依赖项**: ``` patchelf --add-needed libcheat.so libil2cpp.so ``` ### 2. 在内存中定位游戏 在加载时,游戏尚未完全初始化,因此后台线程会等待 `libil2cpp.so`,然后从导出的 symbol 中校准加载基地址: ``` void* p = dlsym(handle, "il2cpp_init"); uintptr_t base = (uintptr_t)p - RVA_il2cpp_init; // RVA from Il2CppDumper ``` 随后,每个函数/字段的地址即为 `base + RVA`。 ### 3. 运行时函数 hook 我们使用 [**And64InlineHook**](https://github.com/Rprop/And64InlineHook) 对 相关的 IL2CPP 方法放置 inline trampoline hook,例如: ``` A64HookFunction(base + RVA_Team_getGold, (void*)h_getGold, (void**)&o_getGold); ``` 每个 hook 会决定是返回作弊值还是调用原始函数。 ### 4. 仅玩家作弊(队伍检测) 金币、人口、伤害等数据存在于一个共享的 `Team` 类中,该类被**双方** 军队共同使用,因此盲目修补也会强化敌方。我们每帧 hook 一次 `GameController.Update()` 来缓存玩家队伍 (`GameController.FriendlyTeam`,字段偏移量 `0x60`)的指针,然后每个 hook 在生效前都会校验身份: ``` if (self == g_friendly) return 999999; // only for the player ``` 对于伤害,每个 `Unit` 在偏移量 `0x3D0` 处都携带有其队伍信息,因此 一击必杀和无敌模式可以精准地作用于正确的阵营。 ### 5. 从反汇编中修补静态字段 军械库的“升级点数”计数器是一个**静态字段** (`GameSaveData.UpgradePoints`)。它没有可以 hook 的 getter —— UI 直接基于原始值控制按钮状态。因此,我们完全按照游戏自身代码的 方式来定位它。反汇编 `GameSaveData.SpendUpgradePoint()` 可以发现: ``` adrp x19, ... ; class-pointer slot ldr x19, [x19, #0x848] ldr x0, [x19] ; Il2CppClass* GameSaveData ldr x8, [x0, #0xb8] ; Il2CppClass.static_fields ldr w20, [x8, #0x50] ; UpgradePoints ``` 我们复现了该指针链(`**(base + 0x24d4848)` → `+0xB8` → `+0x50`)并 锁定该值,同时加入了完整性检查,确保错误的偏移量永远不会导致崩溃。 ### 6. 实时配置 ## 🔨 从源码构建 已在 **aarch64**(Termux / 设备本身的 aarch64 Ubuntu proot 环境)上测试, 这非常方便,因为工具链可以直接在同一部手机上运行。标准的 Android NDK 也可以。 **环境要求:** `clang`(Android/aarch64 目标平台),`patchelf`,`zipalign`, `apksigner`,`python3`,以及针对你的游戏版本的 [Il2CppDumper](https://github.com/Perfare/Il2CppDumper) 输出(用于获取 RVA)。 ``` # 1. 编译 native library bash scripts/build.sh # -> build/libcheat.so # 2. 将其注入到你从自己的设备中提取的已合并(单一)APK 中, # 重新打包、对齐并签名 bash scripts/package.sh path/to/StickWarLegacy.apk my-keystore.jks ``` 具体的命令请查看 [`scripts/`](scripts/)。位于 [`src/libcheat.cpp`](src/libcheat.cpp) 顶部的 RVA 和字段偏移量是针对某一个特定的游戏版本 (global-metadata **v31**)的;如果你的版本不同,请使用 Il2CppDumper 重新生成它们。 ## 📱 安装 1. 卸载原版游戏。 2. 安装你在上面构建的、已签名的修改版 APK。 3. 启动游戏,然后根据个人喜好编辑 `StickWarCheats.txt`。 ## 🗺️ 路线图 - [ ] **游戏内悬浮菜单** —— 一个可拖拽的悬浮按钮,用于打开 带有各种开关的屏幕面板,从而无需编辑文件。(计划通过 ImGui/EGL overlay 或原生 Android 悬浮窗实现。) - [ ] 从 `global-metadata.dat` 自动检测 RVA,以支持多个游戏版本。 - [ ] 可配置的数值(金币数量、伤害倍数)。 ## 📄 许可证 [MIT](LICENSE) © 2026 NX-developer. *Stick War: Legacy* 是其各自所有者的商标。本项目不受 游戏开发者赞助、认可或与其有任何关联。本项目不发布 任何游戏资产或代码 —— 仅包含原创的工具和文档。
标签:Android, DSL, Hook, IL2CPP, Unity, 云资产清单, 动态注入, 游戏模组, 移动端开发, 逆向工程