腾讯游戏安全大赛安卓2023初赛复现


Tencent_Android2023初赛复现

0x0 前言 学习的文章链接

https://bbs.kanxue.com/thread-276893.htm

https://bbs.kanxue.com/thread-276896.htm#msg_header_h2_2

https://bbs.kanxue.com/thread-276949.htm

可以看过以上三篇文章再看我的复现,主要是扩展细节和记录我的复现

0x1 获取flag_修复so文件

题目要求游戏获得1000分出现flag,解包apk发现unity打包的游戏,第一步思路通过github上的工具il2cppdumper(如何使用在我的文章D3MUG中有详细操作)生成信息和函数名。然后发现无法修复就需要动态解密后的so文件(调试的时候即可发现不一样,有自解密)。

第一种文章中的frida_hook方法dump so(用的是fallw1nd师傅文章中的代码)

function DumpIL2CPP() {
    var libil2cpp = Process.getModuleByName("libil2cpp.so");
  	 WriteMemToFile(libil2cpp.base, libil2cpp.size, 'libil2cpp.so');
}

function main() {
  HookLibWithCallback('libil2cpp.so', DumpIL2CPP);
}

setImmediate(main);

第二种文章中的方法使用gg修改器动态dump so

https://gameguardian.net/download 下载链接

注意这个工具需要root以及模块支持

dump下来之后拉入ida会发现很多地址函数爆红,使用010editor工具,在模板中下载elf格式然后f5加载,将两个so对比会发现dump下来的so少了很多,将缺的从原来的so中复制过去即可,拉入ida就正常了最后就是修复函数名和结构体回去,还是在d3mug文章中有写到如何在ida中修复。

0x2 获取flag_反调试

在上面的文章中可以看到有啥反调试,这里记录下我尝试绕过的过程

re.frida.server 改名为fs_64 运行命令 ./fs_64 -l 0.0.0.0:19233 另起cmd转发端口adb forward tcp:19233 tcp:19233 frida 执行命令frida -H 127.0.0.1:19233 -f com.com.sec2023.rocketmouse.mouse -l .\tecent_hook.js

|_|sher师傅的方法发现延时弹窗 hook sleep函数打印调用函数找到检查的关键代码(思路1)

function AntiDebug()
{
    var sleep_addr = Module.findExportByName(null, "sleep");
    var sleep = new NativeFunction(sleep_addr, "void",["int"]);
    Interceptor.attach(sleep,
    {
        onEnter: function (args)
        {
            args[0] = ptr(1000000);
            console.log("hooked sleep");
            console.log('sleep called from:\n' + Thread.backtrace(this.context, Backtracer.ACCURATE).map(DebugSymbol.fromAddress).join('\n') + '\n');
        },
        onLeave: function (returnValue)
        {
        }
    })
}
AntiDebug();

juice4fun师傅使用github rwProcMem33的工具来进行硬断crc检测的位置(思路2),需要将驱动编译出来刷进手机内核,还需要编译出工具,我只编译出了客户端,服务端编译环境搭不起来,以后买pixel了再试试

https://blog.csdn.net/qq_46832407/article/details/129971512

https://www.bilibili.com/video/BV1hR4y1k795/?spm_id_from=333.880.my_history.page.click&vd_source=2fcdd1bcbcd68497824663b16df7d4ef

这是我尝试刷内核时学习的博客和b站视频,我的小米mix2s刷不起来

ida调试名字为as64 运行命令 ./as64 -p 19234 另起cmd转发端口adb forward tcp:19234 tcp:19234

我自己尝试的方法挂起所有线程(思路3)

def suspend_other_thread():
    current_thread = idc.get_current_thread()
    thread_count = idc.get_thread_qty()
    for i in range(0, thread_count):
        other_thread = idc.getn_thread(i)
        if other_thread != current_thread:
            idc.suspend_thread(other_thread)

调试的时候刚断住,ida运行这段python代码挂起所有线程,然后在ida的右边线程窗口一个一个恢复,发现只要是把thread名字挂起即可 一般有3个,缺点就是无法运行游戏了,但是丝毫不影响调试输入mod menu 然后就可以任意输入调试断住关键代码了

8

0x3 获取flag_getflag

获取flag需要游戏金币超过1000,尝试在so中搜索关键英语coin mouse这些(我一直想如果函数名没有正经的取,直接加大难度)怎么分析上面的文章都很详细,我这里就是把判断1000改成了判断0,进去就打印flag

function main() {
    var libil2cpp = Process.getModuleByName("libil2cpp.so");
    var insn = libil2cpp.base.add(0x4653CC);
    Memory.protect(insn,4,"rwx");
    insn.writeByteArray([0x1F,00,00,0x71]);
}
setImmediate(main);

0x4 分析cheat_encrypt_libsec2023_3B9D4

怎么算出是跳转到这个地址的

9

一直点进函数到这里,不能f5,看汇编,然后这里有一个BR跳转hook这里的x2

主要看13B8DD4的代码位置即可,其他是我调试hook其他位置的代码

function hook_System_Convert__ToUInt64_8763844(){
  var libil2cpp = Module.findBaseAddress("libil2cpp.so");
  if(libil2cpp){
    // console.log("libil2cpp:",libil2cpp);
    var System_Convert__ToUInt64_8763844 = libil2cpp.add(0x85B9C4);
    var SmallKeyboard$$iI1Ii_4610736=libil2cpp.add(0x465998);
    var call_13B8DD4 =libil2cpp.add(0x13B8DD4);
    console.log("System_Convert__ToUInt64_8763844 addr:",System_Convert__ToUInt64_8763844);
    Interceptor.attach(System_Convert__ToUInt64_8763844,{
      onEnter: function(args){
        console.log("onenter:",args[0],args[1]);
      },onLeave: function(retval){
        console.log("retavl:",retval);
      }
    });

    Interceptor.attach(SmallKeyboard$$iI1Ii_4610736,{
      onEnter: function(args){
        console.log("SmallKeyboard$$iI1Ii_4610736:onenter:",args[0],args[1]);
      },onLeave: function(retval){
        console.log("SmallKeyboard$$iI1Ii_4610736:retavl:",retval);
      }
    });

    Interceptor.attach(call_13B8DD4,{
      onEnter: function(args){
        console.log("call_13B8DD4:onenter:",this.context.x2);
      },onLeave: function(retval){
        console.log("call_13B8DD4:retavl:",this.context.x2);
      }
    });

    var call_13B8DD0 = libil2cpp.add(0x13B8DD0);
    Interceptor.attach(call_13B8DD0,{
      onEnter: function(args){
        console.log("call_13B8DD0:onenter:",this.context.x8,this.context.x2);
      },onLeave: function(retval){
        console.log("call_13B8DD0:retavl:",this.context.x8);
      }
    });
  }
}

1

动调查看libsec的基址

2

hook的跳转地址相减即是

3

libsec.so+0x31164然后点进函数中到3B9D4函数中

5

动调可以看见我们的输入我输入的是666666 16进制为 0xa2c2a x0是存储的位置

4

可以看到混淆csel 然后一个跳转BR,这里BR调试起来可以知道具体怎么走,|_|sher师傅文章中写了具体的静态patch和如何计算跳转地址修改即可,我这里就举一个例子

6

mov x8,xzr xzr和wzr等于0寄存器 理解成赋值0,与2进行比较,w9赋值0x28 csel先看最后一位cc 判断的条件无符号小于,意思是if(x8<2) x10=xzr else x10=x9 0ff_72c40里面存了地址,根据x10的索引取出地址加上一个固定基址,最后跳转,我这里是已经patch过的。所以patch只需要根据什么的cmp跳转条件来patch跳转判断即可,GE代表大于等于就跳,相当于x8大于等于2就跳转,不然就往下。

7

代码还是比较清晰的,逆算法就不贴了,师傅们的文章中都有

0x5 分析cheat_encrypt_libsec2023_3A924

10

总体就是搭建一个java环境,解密函数名,传入我们的输入,apk中没有encrypt,我们动态调试直接可以dump dex下来也可以使用工具脚本

frida-dexdump 命令 frida-dexdump -H 127.0.0.1:19234 -f com.com.sec2023.rocketmouse.mouse

11

在classes07中

3个反编译工具中 GDA4.06 pro jadx jd-gui

GDA整体反编译的最好,就是逻辑写法反编译会有点错误,复制到android studio不能直接跑起来,break 和 continue的逻辑有问题,也不知道是不是android studio的问题。

14

jadx相比较差 好的一点就是data反编译的好

15

将dex转换成jar 用jd-gui反编译 算法的位置效果特别好,反编译到一起,移位也很清晰

16

17

第一种方法使用在线网站把字符串都hash出来手动或脚本计算 自己理清控制流。

第二种方法使用andriod studio 调试这串java代码跟踪代码流,就是需要将代码优化一下先,死住的地方还是需要静态重推算一下,如果可以像ida反编译效果那么好就好了拉过来就调试。

第三种方法解混淆,搜了半天BlackObfuscator的解混淆,有师傅会真得出篇wp。

0x6 分析cheat_encrypt_libil2cpp_465AB4

12

13

动调可以发现回到了libil2cpp中,后面就是vm位置的分析实在不会。

0x7 最后的xtea

18

动调取出key即可

20

0x8 外挂启动判断

19

var libil2cpp = Process.getModuleByName("libil2cpp.so");
var insn = libil2cpp.base.add(0x465D14);
console.log(hexdump(insn));
console.log("Patching..");
Memory.protect(insn,4,"rwx");
insn.writeByteArray([0x1f,0x20,0x03,0xd5,0x1f,0x20,0x03,0xd5]);

文章作者: Blue
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Blue !
评论
  目录