我分析的这款应用是韩国某大型娱乐公司旗下的爱豆聊天App。先选择想聊天的爱豆,然后付费就能和TA聊天了,可以和TA主动发消息。也能看到TA的日常动态。这个应用的包名是:Y29tLmV2ZXJ5c2luZy5seXNu,版本:MS42LjEw。调试时为最新版。本文有的地方参考了GPT,有错误的还请大家指正。
有了这个软件,你可以和下图的或其他爱豆聊天了。
使用的是Root过的Google Pixel 3 手机,手机存在的风险有以下几点:可以看到这个应用至少检测到了我的两个风险,frida和root。frida脚本如下:输出结果如下:这说明检测逻辑位于libdxxcuxd.so 。接下来就应该对这个so进行分析了。先看看它有哪些初始化函数,现在的壳或者风险检测组件都喜欢把检测的逻辑放在这里,如下图所示。 只有DT_INIT_ARRAY 类型的函数,没有DT_INIT 类型的。如果有DT_INIT 类型的,那么我们优先看DT_INIT 类型的,因为它的执行时间早于DT_INIT_ARRAY 类型的函数。且两者都优先于JNI_OnLoad执行。如下图所示。
有两个初始化函数,为了方便阅读,我已经重命名了。先说说调试的结论,要想用frida绕过这个风险检测,直接nop一个函数是不行的,因为会各种各样奇怪的崩溃问题。所以个人觉得更好的做法是修改跳转,让程序检测不出来即可。这个函数如下图所示。
GPT回答是:Android App 进程里:
/app_process64 或者:com.xxx.xxx 取决于:
是否被 zygote 派生
有没有改 argv[0]
有没有调用 setproctitle
是否做了反调试/伪装
很多壳、加固、反作弊都会检查它。我的手机的值如下:看到字符串.sandbox 和com.lbe.parallel ,说明它在检测沙箱、双开环境。很多虚拟环境,如VirtualApp,双开助手,平行空间,VirtualXposed。会注入:SOMETHING=.sandbox 。或者包含路径/data/user/0/com.xxx.sandbox/ 。com.lbe.parallel 是平行空间(Parallel Space),著名的双开框架。检测environ 是因为沙箱特别喜欢修改环境变量,例如:或者添加:因此environ 是反虚拟化的重要检测点。sub_294E0中调用了my_crc32 来检查内存,偏移是sub_10B44 。
下图是sub_294E0 的伪代码,含注释。
可以看到从A4078处开始,检查10CA8h个字节的内存crc32值。sub_294E0 是被init_arr1 调用的,首次调用时记下crc32到全局变量dword_A4088 ,之后被调用时对比这段内存是否和最初的保持一致,如果不一致,就说明内存被修改了并调用Kill_15DF0 以创建线程的形式退出程序。LOG_7E2A8 是日志函数,它会打印出风险字符串,也是弹窗显示的文字。本小节的 sub_294E0 在别处被引用多次,说明有多个地方做了内存完整性检查,因此我们要注意。sub_164A8 检查了_progname 是否含blackdex 字符串,blackdex是一款脱壳的工具,自然也被组件视为风险因素了。
这个函数位于sub_3DDB4,且我使用的frida版本是16.5.9的。有计算_progname的crc32,和安装异常处理的sigHandler。
然后就是经典的检测frida环节。调用了scandir 搜索/proc/%d/task ,%d是进程PID。看看它有哪些线程?再读取/proc/%s/comm ,看看有没有和frida相关的字符串,有就说明App被frida“入侵”了。
这段代码里有好几个flag,可以说是用于做风险分数评估的。根据这些分数风控组件来决定要不要继续执行。为什么要看/proc/%d/task 和/proc/%s/comm 呢?先用frida注入一个自己写的App试试看。列举出有哪些线程。 然后逐个线程的看。
所以说这是libdxxcuxd.so 在这里检查frida的原因。不要忘了,本节的sub_3DDB4 还检查了其它的风险,调用了函数RiskDetect_1D25C ,如下图所示。 检测的字符串有以下:(/proc/%d/maps中)返回0表示没有风险,-1表示有风险。这个函数代码少,暂时不是绕过反调试的关键。
sub_1017C 如下图所示。
dlopen_46914是自定义的dlopen,v19是输出变量,存放so文件各区段的关键信息。dlsym_10138 和dlsym_4B3E8 都是寻找符号的函数,就是找到对应函数名的地址。其中dlsym_10138 内部调用了dlsym_4B3E8 。 寻找/linker64里的关键函数,然后放到全局变量里。先寻找切入点。因为风控组件的代码启动的比较早,所以我习惯在linker即将.init_proc 时注入frida的脚本。把linker64 拷贝到电脑上。用IDA打开google_pixel3_linker64 ,即拷贝出来的linker64 。搜索关键字call_constructors ,得到这个函数和偏移是2C274 。 frida脚本如下:然后就能打印出以下内容:这说明我们的代码是注入的比较早的。我们得先绕过frida检测,才能绕过其它的风险检测。该函数被sub_3DDB4 调用。这个函数只是检测了许许多多的风险字符串,内部调用的只是字符串拷贝或者寻找子串的函数,没有额外的影响线程运行的函数。因此把它的返回值改为0即可。这个函数头部的指令可以改为如下:对应的frida脚本如下:调用: 我们不能粗暴地把scandir 改成非法的,比如-1 ,这样按照执行流程的话会让App退出的。
此外,还有一个全局变量flag2_A5D9C 的值要是0x20 。即绿色部分的指令应该被执行。再来看看init_arr1 处的代码,如下图所示。
如果flag2_A5D9C & 0x20 为0,则App会退出。所以此时的想法是让程序在执行scandir 时直接跳转至loc_3E928 处,即不让风控组件扫描目录。
这样就能让flag2_A5D9C & 0x20 不为0了,也就不会调用kill_15FD0 函数了。经过调试flag2_A5D9C 可能会被其它的线程或函数修改成flag2_A5D9C & 0x20 为0的情况,为了保险起见,我们还要看哪里调用了sub_3DDB4 。有两处调用了sub_3DDB4 ,如下图所示。
把条件跳转TBNZ W1, #5, loc_100E8 ,改成B loc_100E8 。 把TBNZ W1, #5, loc_8419C 改成b loc_8419C 。frida实现强制跳转的代码如下:调用:写好的frida脚本此时如下:但是有报错:重点是:signal 11 (SIGSEGV), code 2 (SEGV_ACCERR), fault addr 0x7a4299fcbf 和pc 0000007a0c45a918 这有助于我们锁定报错的位置。7a0c45a
...(已截断)
---
来源: 看雪论坛
原文链接: https://bbs.kanxue.com/thread-291227.htm
和爱豆更近一步——某爱豆聊天App反调试绕过
375 浏览
12 回复
期待更多优质内容的分享,论坛有你更精彩!
感谢分享
学习一下
向大佬学习
tql
终于找到提供app包名的帖子了,其他帖子一个包名都没有提供,这让新人想跟练的机会都没有,感谢UP
学习
学习一下
666666666,xuexile
感谢分享
感谢分享
感谢分享