首页
课程
问答
CTF
社区
招聘
峰会
发现
排行榜
知识库
工具下载
看雪20年
看雪商城
证书查询
登录
注册
首页
社区
课程
招聘
发现
问答
CTF
排行榜
知识库
工具下载
峰会
看雪商城
证书查询
社区
逆向工程
发新帖
14
11
[原创]一次完整的 Unity Mono 安卓游戏逆向:Frida Hook 绕过碰撞死亡判定
发表于: 2025-12-28 12:52
19141
[原创]一次完整的 Unity Mono 安卓游戏逆向:Frida Hook 绕过碰撞死亡判定
我是jet
2025-12-28 12:52
19141
# Android安卓游戏Unity Mono 游戏逆向实战:从 APK 到 Hook libmono.so 绕过死亡判定 ## 前言 最近在分析一款 **极限摩托基于手机重力控制的 Unity 游戏**:  - 通过手机 **前后翻转控制角色** - 人物只要 **发生碰撞(翻车 / 头部触地)就会立即失败** - 没有明显的数值判定,属于典型的 **物理 + 碰撞触发死亡** 本文完整记录了我 **从 APK 分析 → 判断 Unity 架构 → Hook Mono Runtime → 精准拦截死亡函数** 的全过程。 **最终效果:** > 人物发生碰撞也不会死亡,游戏可正常继续运行。 --- ## 一、实验环境 ### 游戏截图   ### 我使用的设备 & 工具版本 - **Android 10 真机(arm64)** - **Frida版本**:17.5.2 - **Frida Server版本**:`frida-server-17.5.1-android-arm64` - **Python版本**:3.10.0 - *手机不方便可以使用手机模拟器* ### Frida Server 启动 上传到手机: ```bash adb push frida-server-17.5.1-android-arm64 /data/local/tmp/ ``` ```bash adb shell chmod +x /data/local/tmp/frida-server-17.5.1-android-arm64 ``` 启动frida-server-17.5.1-android-arm64 ```bash adb shell /data/local/tmp/frida-server-17.5.1-android-arm64 ``` --- ## 二、从 APK 入手:判断游戏架构 ### 1️⃣ 解包 APK ```bash apktool d trial.apk ``` 重点关注: * `AndroidManifest.xml` * `lib/armeabi-v7a` / `lib/arm64-v8a` * `assets/` --- ### 2️⃣ 查看 so 文件(关键判断点) 在 `lib/arm64-v8a/` 目录下发现: ``` libmono.so libu.so ``` 同时: * ❌ 不存在 `libil2cpp.so` * ❌ 不存在 `libunity.so`(部分 Mono 游戏本来就没有) ### ✅ 结论 > **这是一个 Unity Mono 架构游戏(非 IL2CPP)** --- ## 三、确认 C# 脚本存在 在: ``` assets/bin/Data/Managed/ ``` 中可以看到: ``` Assembly-CSharp.dll UnityEngine.dll ``` #### Assembly-CSharp.dll 可以使用ILSpy工具打开,可以直接看到关键代码Bone::OnCollisionEnter,进行分析  说明: * 游戏逻辑由 **C# 编写** * 运行在 **Mono VM** * 实际执行发生在 **libmono.so** --- ## 四、为什么选择 Hook libmono.so ### ❌ 不直接修改 DLL 的原因 * 需要重打包 APK * 可能触发签名 / 完整性校验 * 不利于动态调试 ### ✅ Hook Mono Runtime 的优势 * 不修改 APK * 可实时观察 C# 函数调用 * 能拦截 **Unity 生命周期 / 碰撞函数** --- ## 五、锁定关键函数:mono_runtime_invoke ### Mono 执行模型简化图 ``` Unity 物理 / 碰撞 ↓ C# 脚本 (Update / OnCollisionEnter) ↓ IL Code ↓ mono_runtime_invoke ↓ Native 执行 ``` > **所有 C# 方法最终都会经过 `mono_runtime_invoke`** 这意味着: > Hook 一个函数,就能观察并控制所有 C# 方法调用。 --- ## 六、附加进程并 Hook ### 1️⃣ 查找游戏 PID ```bash adb shell ps -A | grep com.galapagossoft.trial ``` 输出示例: ``` u0_a236 19480 ... com.galapagossoft.trial ``` --- ### 2️⃣ Frida Attach ```bash frida -U -p 19480 -l mono_base.js ``` --- ## 七、Hook 脚本(核心代码) ```js console.log("[*] mono_base.js loaded"); var mono = Process.findModuleByName("libmono.so"); if (!mono) { console.log("libmono.so not found"); return; } var mono_method_get_name_ptr = mono.getExportByName("mono_method_get_name"); var mono_runtime_invoke_ptr = mono.getExportByName("mono_runtime_invoke"); var mono_method_get_class_ptr = mono.getExportByName("mono_method_get_class"); var mono_class_get_name_ptr = mono.getExportByName("mono_class_get_name"); var mono_method_get_name = new NativeFunction( mono_method_get_name_ptr, "pointer", ["pointer"] ); var mono_method_get_class = new NativeFunction( mono_method_get_class_ptr, "pointer", ["pointer"] ); var mono_class_get_name = new NativeFunction( mono_class_get_name_ptr, "pointer", ["pointer"] ); var orig_mono_runtime_invoke = new NativeFunction( mono_runtime_invoke_ptr, "pointer", ["pointer", "pointer", "pointer", "pointer"] ); Interceptor.replace( mono_runtime_invoke_ptr, new NativeCallback(function (method, obj, params, exc) { var klass = mono_method_get_class(method); var className = mono_class_get_name(klass).readCString(); var methodName = mono_method_get_name(method).readCString(); // 关键:拦截碰撞触发 if (className === "Bone" && methodName === "OnCollisionEnter") { console.log("[BLOCK] " + className + "::" + methodName); return ptr(0); } return orig_mono_runtime_invoke(method, obj, params, exc); }, "pointer", ["pointer", "pointer", "pointer", "pointer"]) ); ``` --- ## 八、分析过程与关键突破 ### 1️⃣ 先打印观察调用 日志中依次出现: ``` Fork::Update Fork::OnCollisionStay FailController::OnGUI Bone::OnCollisionEnter ``` --- ### 2️⃣ 排除错误目标 * `FailController::OnGUI` 只是 UI 显示失败画面,不是死亡原因 * `FailController::Start` 失败后的初始化逻辑 --- ### 3️⃣ 真正的死亡触发点 ```text Bone::OnCollisionEnter ``` 这正好符合游戏机制: > **人物因重力翻转发生碰撞 → 立即失败** --- ## 九、最终效果 成功拦截后: * 人物发生碰撞 **不再死亡** * 物理系统正常 * 游戏流程可继续 ✅ **无需修改 APK** ✅ **无需重打包** ✅ **精准绕过失败判定** --- ## 十、总结 本文完整展示了一条 **Unity Mono 游戏逆向的通用思路**: 1. 从 APK 判断 Unity 架构 2. 确认 Mono 而非 IL2CPP 3. 锁定 libmono.so 4. Hook `mono_runtime_invoke` 5. 通过 Runtime 级分析定位关键 C# 方法 6. 精准拦截 `OnCollisionEnter` 实现逻辑绕过 > **理解引擎执行模型,比盲目改代码更重要。** --- ## 后记 这套方法同样适用于: * Unity Mono 手游 * 碰撞 / 判定 / 失败逻辑分析 * 无源码、无符号环境下的动态逆向 后续我会继续分享更多 Unity / Mono / Frida 实战分析。
登录后可查看完整内容
冰与火的战歌:Windows内核攻防实战高级班!从零到实战,融合AI与Windows内核攻防全技术栈,打造具备自动化能力的内核开发高手。
最后于
2025-12-28 13:11 被我是jet编辑 ,原因:
#调试逆向
收藏
・
14
点赞
・
11
打赏
分享
分享到微信
分享到QQ
分享到微博
赞赏记录
参与人
雪币
留言
时间
atom2024
非常支持你的观点!
2026-6-2 16:45
andy张刘
为你点赞!
2026-3-3 17:30
西提熊
非常支持你的观点!
2026-2-4 14:33
零_721409
你的分享对大家帮助很大,非常感谢!
2026-1-23 10:25
孤独的街
这个讨论对我很有帮助,谢谢!
2026-1-11 12:19
毛民8868
谢谢你的细致分析,受益匪浅!
2026-1-9 17:07
Cherzsh
为你点赞!
2026-1-8 09:39
x_req
感谢你分享这么好的资源!
2026-1-3 16:34
cr_lgdx
期待更多优质内容的分享,论坛有你更精彩!
2026-1-2 19:16
小柯南
感谢你的贡献,论坛因你而更加精彩!
2025-12-29 15:28
我的小拇指啊
期待更多优质内容的分享,论坛有你更精彩!
2025-12-28 23:19
查看更多
赞赏
×
1 雪花
5 雪花
10 雪花
20 雪花
50 雪花
80 雪花
100 雪花
150 雪花
200 雪花
支付方式:
微信支付
赞赏留言:
快捷留言
感谢分享~
精品文章~
原创内容~
精彩转帖~
助人为乐~
感谢分享~
最新回复
(
5
)
x1aob1n
雪 币:
3
能力值:
( LV1,RANK:0 )
在线值:
发帖
0
回帖
6
粉丝
1
关注
私信
x1aob1n
2
楼
大佬可以来个apk的链接吗,网上找的都是没有arm64,lib的包体
2026-1-9 01:41
0
毛民8868
雪 币:
703
活跃值:
(531)
能力值:
( LV2,RANK:10 )
在线值:
发帖
2
回帖
7
粉丝
2
关注
私信
毛民8868
3
楼
加一
2026-1-9 17:08
0
我是jet
雪 币:
247
活跃值:
(275)
能力值:
( LV2,RANK:10 )
在线值:
发帖
3
回帖
1
粉丝
9
关注
私信
我是jet
4
楼
极限摩托(Trial X) apk:
b4fK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6%4N6%4N6Q4x3X3g2H3j5$3S2G2L8h3g2Q4x3X3g2F1k6i4c8Q4x3V1k6Y4j5h3#2W2M7#2)9J5c8U0f1#2z5o6f1K6y4#2)9J5k6h3S2@1L8h3H3`.
2026-1-11 08:53
0
huangjw
雪 币:
6688
活跃值:
(11872)
能力值:
( LV2,RANK:10 )
在线值:
发帖
0
回帖
511
粉丝
2
关注
私信
huangjw
5
楼
2026-1-11 13:28
0
A1ter
雪 币:
0
能力值:
( LV1,RANK:0 )
在线值:
发帖
0
回帖
2
粉丝
0
关注
私信
A1ter
6
楼
使用雷电模拟器,frida无法找到libmono.so。因为模拟器对arm库做了一层转译,所以arm库都是非标准方式加载的,所以libmono.so对于frida来说是隐藏的无法hook。网上也都没看到带有x86_64版本的so。好像只能上真机
2026-2-23 15:50
0
游客
登录
|
注册
方可回帖
回帖
表情
雪币赚取及消费
高级回复
返回
我是jet
3
发帖
1
回帖
10
RANK
关注
私信
他的文章
[原创]神庙逃亡(Temple Run)IL2CPP 逆向实战:从 APK 到 Frida 实现角色无敌
3785
[原创]逆向实战:如何用机器码把 x64dbg 的汇编精准定位到 IDA / Ghidra 的 C 代码
3155
[原创]一次完整的 Unity Mono 安卓游戏逆向:Frida Hook 绕过碰撞死亡判定
19141
关于我们
联系我们
企业服务
看雪公众号
专注于PC、移动、智能设备安全研究及逆向工程的开发者社区
看原图
赞赏
×
雪币:
+
留言:
快捷留言
为你点赞!
返回
顶部