Il2cpp数据类型解析のC#List

发布于 2020-07-21  1.1k 次阅读


想要修改的思路有更多选择, 就需要深入解析游戏内的数据结构

前言

上次为了能够识别并且打印C#的字符串, 搓了解析字符串的文章, 能直接输出打印他们的字符串是真的爽
但是光解析字符串是不够的, 数据结构的什么 字典, 列表, 数组 等数据结构, C/CPP是没法直接对接调用的, 如果能把C#写的东西在手机里跑就好了, 所以还是得手动撸代码解析对应的数据结构
这次解析的是算是简单的 List(列表) 结构, 无奈Il2cpp提供的API无法hook上 (真的太麻烦了)

查看API的反汇编

这是一张图.jpg

分析结构

这是一张图.jpg

照抄代码

基本上内存读写 + 内存偏移就好了

测试成果

这是一张图.jpg

结语

好像能通过 Il2cppArray 类型去直接解析, 懒得测试了
将就用着吧

另一种自用的解析

//声明类型
typedef struct Il2CppObject Il2CppObject;
typedef struct Il2CppArrayBounds Il2CppArrayBounds;
typedef uintptr_t il2cpp_array_size_t;
struct Il2CppArray
{
    struct Il2CppObject obj;
    struct Il2CppArrayBounds *bounds;
    il2cpp_array_size_t max_length;
    void *vector[32];
};

//内存偏移
template <class T>
inline T MemoryOff(void *addr, ulong off)
{
    if (addr == nullptr)
        RT("MemoryOff Null Error!") && CCC("Addr is nullprt!");
    return (T)((char *)addr + off);
}

//内存读取
template <class T>
inline T MemoryRead(void *addr, ulong off)
{
    if (addr == nullptr)
        RT("MemoryRead Null Error!") && CCC("Addr is nullprt!");
    return *(T *)((char *)addr + off);
}

//获取到list对象实体
auto list = MemoryRead<Il2CppObject *>(this, 0x8);

//解析list对象信息
auto list_arr = MemoryRead<Il2CppArray *>(list, 0x8);//32位偏移
auto list_size = MemoryRead<int>(list, 0xC);//32位偏移

auto items = list_arr->vector;
auto length = list_size;//list类型读取arr的size是错的
LOGE("items length: %i", length);
for (int i = 0; i < length; ++i)
{
    auto obj = item[i];
    //code...
}

一位被疯狂压榨的底层工作人员