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, 云资产清单, 动态注入, 游戏模组, 移动端开发, 逆向工程