gslab2021 初赛 - 安卓客户端安全 | Xhy’s Blogwp参考
Assembly CSharp.dll文件已加密,路径为X:\GameSafety\Game2021\安卓客户端题目\初赛题目\RocketMouse\assets\bin\Data\Managed
mono引擎的unity游戏,包名com.personal.rocketmouse
启动游戏会弹窗hacker detect并退出,在com.tencent.games.sec2021.Sec2021MsgBox下找到onDismiss方法调用系统函数exit
查找show的交叉引用找到com.tencent.games.sec2021.Sec2021IPC的onNativeEngineResponse方法,猜测调用了native层的函数使进程退出,在ida中找kill函数的交叉引用找到函数sub_1F788,继续查找函数调用链找到1FAA8,该函数被调用了5次
用florida过掉了检测
查看libmono.so发现libmono.so经过了加密,用elf-dump-fix在libmono.so加载之后从内存中dump并修复得到解密后的monodump.so
找到libmono.so的mono_image_open_from_data_with_name方法,此处用于加载Assembly-CSharp.dll文件,发现第一条指令用于跳转到libsec2021.so的sub_1CEDC函数,此函数用于对Assembly-CSharp.dll文件解密

会先判断如果是MZ开头并且路径中没有Assembly-CSsharp.dll文件,就跳转到0x1CF88执行,否则就调用0x1CF4C解密函数,如图,此处会将sec2021.png的0x410B至末尾的数据解密,解密结果为真正加载的Assembly-CSharp.dll,查看函数调用可以看到解密函数为0x1D2A0

其中sub_18CEC为获取dll索引,crc32校验函数为subF3B4正常会返回0,直接把返回值patch成0即可过检测
过完检测之后因为mono_image_open_from_data_with_name函数的第一条指令会完成解密操作,所以可以hook下一条指令,当读取到真正的Assembly-CSharp.dll时在内存中dump出来
|
|
dump完成之后分析dll文件,因为目标为实现无敌,所以只需要修改游戏逻辑中对碰撞的检测即可,定位到MouseController类的OnTriggerEnter2D函数

如果不是金币就会调用HitByLaser函数,所以只要把相应的Dead属性改为false即可,在ida中静态patch,原来为4.1,改为4.0即可

最后只需要把0x1CF88处的跳转指令改成B ,使非MZ开头的dll才执行解密函数,并把原本的dll替换成破解版即可
复现中遇到的问题
-
打开APP就会退出并弹窗"
hacker detect:xxx",后面发现是app检测了tmp目录下是否存在frida/ida相关的东西,更改名称即可过检测 -
使用frida启动APP仍然会退出,是对frida的一些行为进行检测。使用
florida过了检测 -
尝试hook libsec2021.so中的
sub_1F120(字符串解密函数)时,会出现opcode crack的情况,原因未查明,但是通过patch掉退出函数的调用也能过,缺点是只能hook出部分字符串 -
在dump内存的时候,会出现dump不出来的情况,后面检查发现是libmono.so是动态加载的,于是要先hook
dlopen函数,在libmono.so加载之后再进行hook,并执行内存dump -
dump Assembly-CSharp.dll的时候,是根据dll的大小来判断的,目前不清楚具体原因是什么,但是在hook
mono_image_open_from_data_with_name函数的时候发现他加载的文件大小差异比较大,目前猜测是比较所有被加载的dll的大小之后才判断要dump大小为0x2800的dll文件