#随笔-Try to reverse ACE 2023

😭5ea1


这里没有前言


哎三星大虫子三星劫三星瑟庄妮真有实力吧,上了个执事挂机,hook完回来一看收了400层,商店里连刷6只大虫子直接3星了,要啥运营啊


apk的本地库里有libil2cpp.so,放ida看一下,发现是加密过的,看不了
1
因为在实际调用过程中,肯定不可能直接使用这个被加密的lib库,所以可以考虑使用fridahook把要的库dump下来
这里可以采用getModuleByName的方法,直接传进去lib_name,获取地址,然后用lib.base和lib.size来读取内容
一开始我写了如下代码:

function dump_so(so_name){
    Java.perform(function() {
        var libso = Process.getModuleByName(so_name);
        console.log("libso base address: " + libso.base.toString(16));
        console.log("libso size: " + libso.size.toString(16));
        console.log("libso path: " + libso.path);
        console.log("libso name: " + libso.name);

        Memory.protect(ptr(libso.base), libso.size, 'rwx');

        var data = Memory.readByteArray(libso.base, libso.size);
        var file = new File(/data/local/tmp/dump.so, "wb");
        file.write(data);
        file.flush();
        file.close();
        console.log("libso dumped to " + dump_path);
        console.log("libso dump done!");
    });
}

function main() {
    var so_name = "libil2cpp.so"; 
    dump_so(so_name);
}

setImmediate(main);

但是使用的时候发现两个错:

  1. 在读取的时候,会报错Error: access violation accessing 0x71191e1000
    这个报错的原因可能是因为在lib中有某种防止读取的内存防御措施,这个措施在0x71191e1000这个地址处,所以当我们修改内存权限的时候,要绕过它修改
  2. frida对于应用沙箱外的地址没有操作权限,所以产生的dump.so要在应用沙箱内完成创建

基于上面的两个错误,我们可以得到下面的代码:

function dump_so(so_name){
    Java.perform(function() {
        
        var context = Java.use("android.app.ActivityThread").currentApplication().getApplicationContext();
        var dir = context.getFilesDir().getAbsolutePath();
        
        var libso = Process.getModuleByName(so_name);
        console.log("libso base address: " + libso.base.toString(16));
        console.log("libso size: " + libso.size.toString(16));
        console.log("libso path: " + libso.path);
        console.log("libso name: " + libso.name);

        Memory.protect(ptr(libso.base), libso.size, 'rwx');
        Memory.protect(ptr(libso.base).add(0x13B7000), libso.size - 0x13B7000, 'rwx');

        var data = Memory.readByteArray(libso.base, libso.size);
        var dump_path = dir + "/" + libso.name;
        var file = new File(dump_path, "wb");
        file.write(data);
        file.flush();
        file.close();
        console.log("libso dumped to " + dump_path);
        console.log("libso dump done!");
    });
}

function main() {
    var so_name = "libil2cpp.so"; 
    dump_so(so_name);
}

setImmediate(main);

运行后得到:

libso base address: 7119420000
libso size: 13cc000
libso path: /data/app/~~c4CHbJNFMW6K-83Dl7_psQ==/com.com.sec2023.rocketmouse.mouse-Wo6nAo9UMfyLXh-IViOx-g==/lib/arm64/libil2cpp.so
libso name: libil2cpp.so
libso dumped to /data/user/0/com.com.sec2023.rocketmouse.mouse/files/libil2cpp.so
libso dump done!

由于这个位置需要su权限才能读取,不能直接pull,所以要先复制到共享文件夹,再pull拉取:

adb shell
su
cp /data/user/0/com.com.sec2023.rocketmouse.mouse/files/libil2cpp.so /sdcard/
exit
exit
adb pull /sdcard/libil2cpp.so  

哦,这个位置还要记得保存一下基址,后面要用


拿完解密后的lib后,需要使用Il2CppDumper来获取符号表
这里要用到一个global-metadata.dat,这个dat直接能在apk中解压缩找到:
2

条件完备以后可以使用Il2CppDumper来操作
将这两个文件放入Il2CppDumper的input中后,双击Il2CppDumper.exe进行分析,地址直接填写前面获取的基址即可
3
运行后在output中获得修复的符号表