首页
社区
课程
招聘
[原创]某二游 v4.8版本 IL2CPP Runtime Dump分析
发表于: 2024-7-31 12:33 2775

[原创]某二游 v4.8版本 IL2CPP Runtime Dump分析

2024-7-31 12:33
2775

前言

研究仅供学习交流,如有侵权请联系删除
好久没有登过游戏了,趁着暑假有空来研究学习一下,看看现在版本的保护强度如何

分析

下完游戏,下意识的去找UserAssembly.dll,结果发现找了半天没找到,返回去看到UnityPlayer.dll也没了,懵了一下,然后才看到了264MB的exe...好嘛全给编译到一起了
图片描述
Metadata下也多了个不知道干啥的东西
图片描述

随手过一下保护,然后dump一下直接丢IDA了,跑了近10h才跑完,得到了一个3个多G的idb
本来是想照着Zygisk-Il2CppDumper去写dumper的,后面发现很多函数都内联了,加上结构被魔改,看着太乱了,弄的时候已经大半夜了,有些实在懒得找了,就选择了简单Hook一下 il2cpp::vm::SetupMethodsLocked来获取符号信息了

定位 il2cpp_vm_SetupMethodsLocked

自己编译一份同版本的带pdb的游戏,IDA把两个dll分析完然后对比分析
找交叉引用,可以看到在il2cpp::vm::Class::GetMethods中有调用il2cpp::vm::SetupMethodsLocked
利用一些关键字符串,可以直接从UnityPlayer.dll部分开始找一条链子来定位
ExtractStacktrace->il2cpp_class_get_methods->il2cpp::vm::Class::GetMethods->il2cpp::vm::SetupMethodsLocked
可以看到很多函数都被内联了,结构也都魔改了
图片描述

dump method

ReportRecursionDepthError下可以找到il2cpp_class_get_namespaceil2cpp_class_get_name
图片描述
其他的同理,offset这里就不放了,自己动手找吧哈哈

1
2
3
4
5
6
7
DO_API(0x0, const char*, il2cpp_class_get_namespace, (void* klass));
DO_API(0x0, const char*, il2cpp_class_get_name,      (void* klass));
DO_API(0x0, void*,       il2cpp_class_get_methods,   (void* klass, void** iter));
 
DO_API(0x0, const char*, il2cpp_method_get_name,     (void* method));
 
DO_APP_FUNC(0x0, void, il2cpp_vm_SetupMethodsLocked, (void* klass, void* lock));

在dump的时候我犯了个蠢,在hook函数里直接开始调用il2cpp_class_get_methods了,后面才想起他会调用il2cpp::vm::SetupMethodsLocked,导致无限递归然后炸掉了。可以先把klass存入一个容器里,等游戏全部加载完后再去dump

写了一个简易的dumper,代码主打一个能跑就行哈哈

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
void dump_method(void* klass)
{
    outFile << "// Namespace: " << il2cpp_class_get_namespace(klass) << "\n";
    outFile << "\n\t// Methods\n";
    void* iter = 0;
    while (void* method = il2cpp_class_get_methods(klass, &iter))
    {
        LOGI("0x%x", method);
        uintptr_t p = reinterpret_cast<uintptr_t*>(method)[0];
        if (p) {
            outFile << "\t// RVA: 0x";
            outFile << std::hex << (uint64_t)p - base;
            outFile << " VA: 0x";
            outFile << std::hex << (uint64_t)p;
        }
        else {
            outFile << "\t// RVA: 0x VA: 0x0";
        }
 
        outFile << "\n\t";
        outFile << il2cpp_method_get_name(method) << "(...){ };\n";
    }
 
}
 
void il2cpp_vm_SetupMethodsLocked_Hook(void* klass, void* lock)
{
    klazzs.push_back(klass);
    return CALL_ORIGIN(il2cpp_vm_SetupMethodsLocked_Hook, klass, lock);
}
 
void il2cpp_dump()
{
    DisableLogReport();
    HookManager::install(il2cpp_vm_SetupMethodsLocked, il2cpp_vm_SetupMethodsLocked_Hook);
    // 按回车开始dump
    int a;
    std::cin >> a;
    for (const auto& klass : klazzs) {
        dump_method(klass);
    }
}

部分method的信息就dump出来了
图片描述

点到为止,剩下的其实全是力气活了,事实上有比这更好的dump的方法,这里就不介绍了
有不对的地方还请各位大佬指正哈


[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

最后于 2024-7-31 12:39 被TubituX编辑 ,原因: typo
收藏
免费 2
支持
分享
最新回复 (1)
雪    币: 20
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
2
米忽悠连夜邀请yuro师傅入场
2024-8-12 21:13
0
游客
登录 | 注册 方可回帖
返回
//