Unityil2cpp游戏逆向分析浅析

admin 2026-04-16 04:48:08 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: 本文分析Unityil2cpp游戏逆向过程中遇到的保护机制触发和JSON解析异常问题。针对文件加密状态检测,建议通过内存Dump获取未加密数据;对于NullPointerException错误,提出增加空值校验和异常处理的代码修复方案。文章提供Frida脚本示例和具体代码修改建议,帮助解决逆向分析中的常见技术障碍。 综合评分: 82 文章分类: 逆向分析,移动安全,二进制安全,漏洞分析,安全工具


cover_image

Unity il2cpp游戏逆向分析浅析

原创

云天实验室 云天实验室

哆啦安全

2025年7月3日 08:01 四川

在小说阅读器读本章

去阅读

手游逆向与防护(建议收藏)

威胁手游安全的对象有哪些吗?

手游修改器锁机APP的逆向分析

Unity il2cpp游戏逆向分析技巧

手游安全之cocos2d-x的源码浅析(手游逆向与防护)

搭建云手机(无需Root权限)

Zygisk注入器 – 动动手指轻松注入并隐藏你的SO文件

车载系统的安全启动(Secure Boot)、可信执行环境(TEE)、硬件安全模块(HSM)和固件更新安全

Initializing metadata...Metadata Version: 31Initializing il2cpp file...Applying relocations...WARNING: find JNI_OnLoadERROR: This file may be protected.Il2Cpp Version: 31Searching...CodeRegistration : 798be98MetadataRegistration : 7ca6550Dumping...Done!Generate struct...Done!Generate dummy dll...Done!Press any key to exit...buffer is not enoughException in thread "AWT-EventQueue-0" java.lang.NullPointerException: Cannot invoke "org.json.JSONObject.getJSONArray(String)" because "jsonObject" is null        at Main.getScriptJsonArray(Main.java:423)        at Main.doFunctions(Main.java:290)        at Main.doJob(Main.java:148)        at Main.access$000(Main.java:44)        at Main$1.actionPerformed(Main.java:100)        at java.desktop/javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1972)        at java.desktop/javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2313)        at java.desktop/javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:405)        at java.desktop/javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:262)        at java.desktop/javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:279)        at java.desktop/java.awt.Component.processMouseEvent(Component.java:6626)        at java.desktop/javax.swing.JComponent.processMouseEvent(JComponent.java:3389)        at java.desktop/java.awt.Component.processEvent(Component.java:6391)        at java.desktop/java.awt.Container.processEvent(Container.java:2266)        at java.desktop/java.awt.Component.dispatchEventImpl(Component.java:5001)        at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2324)        at java.desktop/java.awt.Component.dispatchEvent(Component.java:4833)        at java.desktop/java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4948)        at java.desktop/java.awt.LightweightDispatcher.processMouseEvent(Container.java:4575)        at java.desktop/java.awt.LightweightDispatcher.dispatchEvent(Container.java:4516)        at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2310)        at java.desktop/java.awt.Window.dispatchEventImpl(Window.java:2780)        at java.desktop/java.awt.Component.dispatchEvent(Component.java:4833)        at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:773)        at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:722)        at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:716)        at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)        at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86)        at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:97)        at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:746)        at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:744)        at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)        at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86)        at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:743)        at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)        at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)        at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)        at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)        at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)        at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)

根据日志和错误信息分析,该问题涉及‌IL2CPP逆向过程中的文件保护机制触发和JSON解析异常‌,以下是分步解决方案:

一、针对IL2CPP保护机制的处理

‌确认文件加密状态‌

日志中ERROR: This file may be protected表明目标文件(如libil2cpp.so或global-metadata.dat)可能被加固或加密。需检查文件头特征:

正常global-metadata.dat应以魔数AF 1B B1 FA开头,若被加密则熵值较高‌。

使用010 Editor分析文件结构,若发现异常字节或抹除的符号表,需通过内存Dump绕过保护‌。

‌内存Dump未加密数据‌

若静态分析失败,可通过动态注入(如Frida)从内存中提取未加密的global-metadata.dat和libil2cpp.so

// Frida脚本示例:搜索并Dump内存中的global-metadata.datfunction dump_metadata() {    Memory.scan(..., "AF 1B B1 FA", {        onMatch: (address) => {            const file = new File("/path/output.dat", "wb");            file.write(Memory.readByteArray(address, size));            file.close();        }    });}

此方法可绕过文件静态加密,直接获取运行时解密后的数据‌。

二、解决JSON解析异常(NullPointerException)

‌错误根源分析‌

NullPointerException发生在Main.getScriptJsonArray(),原因为jsonObject未初始化或输入数据无效。需检查:

输入JSON文件路径是否正确,文件内容是否为空或格式错误。

确保JSONObject初始化前已通过new JSONObject(inputString)加载有效数据。

代码修复建议‌

在Main.java中增加空值校验和异常处理

// 修改getScriptJsonArray方法public JSONArray getScriptJsonArray(String jsonPath) {    try {        String jsonStr = Files.readString(Paths.get(jsonPath));        if (jsonStr == null || jsonStr.isEmpty()) {            throw new IllegalArgumentException("JSON文件为空");        }        JSONObject jsonObject = new JSONObject(jsonStr); // 显式初始化        return jsonObject.getJSONArray("targetArray");    } catch (Exception e) {        System.err.println("解析失败: " + e.getMessage());        return null;    }}

三、综合调试建议

‌分步验证流程‌

优先解决保护机制:确保global-metadata.dat和libil2cpp.so可被正常解析‌。

再处理JSON异常:通过日志输出中间数据,确认JSON文件路径和内容有效性。

‌工具链检查‌

使用最新版IL2CppDumper(如GitHub Perfare版本),部分旧版本可能不支持高版本Unity生成的元数据‌。

四、扩展资源

若需进一步分析IL2CPP内存结构或加固对抗技术,可参考以下方向:

‌延迟加载优化‌:通过动态加载元数据减少内存占用‌。

‌加固对抗案例‌:某讯libtprt.so加固的逆向分析方法‌。

Android逆向资料(2025)

链接: https://pan.baidu.com/s/18bQwLJgv4vUKgLC-XqtxWg 提取码: 46s4

安全研究资料库大全(2025)

https://pan.quark.cn/s/0812c8cb47a1#/list/share

推荐阅读

JS逆向&APP逆向

APP应用安全检测

App安全检测实践基础

常见APP抓包方法汇总(2025)

APP渗透测试常见工具和方法

iOS APP隐私合规检测的工具和方法

LSPatch和太极框架(免Root)及Magisk

Root和隐藏(Magisk+Ruru+LSPosed)

Android7至Android16系统定制篇(魔改)

Android15无需解锁就能Root的解决方案

基于QEMU/KVM定制Android10至16系统

鸿蒙(HarmonyOS)2.0系统中定制堆栈跟踪方法

Android7至16系统ROM魔改和安全研究篇(建议收藏)

KernelSU Next是Android新兴的内核级Root解决方案

HarmonyOS Next(鸿蒙Next)获取Root权限的解决方案

Android和iOS逆向分析/安全检测/渗透测试框架(建议收藏)

鸿蒙系统(HarmonyOS)常用的日志跟踪命令及相关操作指南

APP漏洞检测之静态动态安全检测APP的常见风险(值得收藏)

永久关闭或修改Android系统的SELinux状态(避免重启后恢复)

HarmonyOS Next(鸿蒙Next)针对APP抓包的工具和抓包方法

Android10至16系统定制中实现同时打印JNI(Native)堆栈和Java堆栈


免责声明:

本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。

任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。

本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我

本文转载自:哆啦安全 云天实验室 云天实验室《Unity il2cpp游戏逆向分析浅析》

评论:0   参与:  0