当前位置:首页>安卓APP>一次完整的 Unity Mono 安卓游戏逆向:Frida Hook 绕过碰撞死亡判定

一次完整的 Unity Mono 安卓游戏逆向:Frida Hook 绕过碰撞死亡判定

  • 2026-10-11 06:25:36
一次完整的 Unity Mono 安卓游戏逆向:Frida Hook 绕过碰撞死亡判定

最近在分析一款极限摩托基于手机重力控制的 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 启动

上传到手机:

adb push frida-server-17.5.1-android-arm64 /data/local/tmp/
adb shell chmod +x /data/local/tmp/frida-server-17.5.1-android-arm64

启动frida-server-17.5.1-android-arm64

adb shell /data/local/tmp/frida-server-17.5.1-android-arm64

二、从 APK 入手:判断游戏架构

1️⃣ 解包 APK

apktool d trial.apk

重点关注:

  • AndroidManifest.xml
  • lib/armeabi-v7a
    /lib/arm64-v8a
  • assets/

2️⃣ 查看 so 文件(关键判断点)

在lib/arm64-v8a/目录下发现:

libmono.solibu.so

同时:

  • ❌ 不存在libil2cpp.so
  • ❌ 不存在libunity.so(部分 Mono 游戏本来就没有)

✅ 结论

这是一个 Unity Mono 架构游戏(非 IL2CPP)

三、确认 C# 脚本存在

在:

assets/bin/Data/Managed/

中可以看到:

Assembly-CSharp.dllUnityEngine.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

adb shell ps -A | grep com.galapagossoft.trial

输出示例:

u0_a236   19480   ...   com.galapagossoft.trial

2️⃣ Frida Attach

frida -U -p19480 -l mono_base.js

七、Hook 脚本(核心代码)

console.log("[*] mono_base.js loaded");varmono = Process.findModuleByName("libmono.so");if (!mono) {    console.log("libmono.so not found");return;}varmono_method_get_name_ptr = mono.getExportByName("mono_method_get_name");varmono_runtime_invoke_ptr = mono.getExportByName("mono_runtime_invoke");varmono_method_get_class_ptr = mono.getExportByName("mono_method_get_class");varmono_class_get_name_ptr = mono.getExportByName("mono_class_get_name");varmono_method_get_name =new NativeFunction(    mono_method_get_name_ptr, "pointer", ["pointer"]);varmono_method_get_class =new NativeFunction(    mono_method_get_class_ptr, "pointer", ["pointer"]);varmono_class_get_name =new NativeFunction(    mono_class_get_name_ptr, "pointer", ["pointer"]);varorig_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) {varklass = mono_method_get_class(method);varclassName = mono_class_get_name(klass).readCString();varmethodName = 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::UpdateFork::OnCollisionStayFailController::OnGUIBone::OnCollisionEnter

2️⃣ 排除错误目标

  • FailController::OnGUI只是 UI 显示失败画面,不是死亡原因

  • FailController::Start失败后的初始化逻辑


3️⃣ 真正的死亡触发点

Bone::OnCollisionEnter

这正好符合游戏机制:

人物因重力翻转发生碰撞 → 立即失败

九、最终效果

成功拦截后:

  • 人物发生碰撞不再死亡
  • 物理系统正常
  • 游戏流程可继续

✅无需修改 APK✅无需重打包✅精准绕过失败判定

十、总结

本文完整展示了一条Unity Mono 游戏逆向的通用思路:

  1. 从 APK 判断 Unity 架构
  2. 确认 Mono 而非 IL2CPP
  3. 锁定 libmono.so
  4. Hookmono_runtime_invoke
  5. 通过 Runtime 级分析定位关键 C# 方法
  6. 精准拦截OnCollisionEnter实现逻辑绕过

理解引擎执行模型,比盲目改代码更重要。

这套方法同样适用于:

  • Unity Mono 手游
  • 碰撞 / 判定 / 失败逻辑分析
  • 无源码、无符号环境下的动态逆向

后续我会继续分享更多 Unity / Mono / Frida 实战分析。

看雪ID:我是jet

https://bbs.kanxue.com/user-home-1062757.htm

*本文为看雪论坛优秀文章,由 我是jet原创,转载请注明来自看雪社区

# 往期推荐

逆向分析某手游基于异常的内存保护

解决Il2cppapi混淆,通杀DumpUnityCs文件

记录一次Unity加固的探索与实现

DLINK路由器命令注入漏洞从1DAY到0DAY

量子安全 quantum ctf Global Hyperlink Zone Hack the box

球分享

球点赞

球在看

点击阅读原文查看更多

最新文章

随机文章