0x00 前言
很少的时候会遇到ARM架构的APP,存在frida检测的情况,这种情况下呢,没有办法直接使用ARM64的ret指令来直接让检测函数给返回。于是需要自己动手来分析so文件。
0x01 dumpSo
两个APP均是梆梆加固的,众所周知梆梆企业壳也是有加固过的,所以要dump一下so文件。使用elf-dump-fix工具来dump so文件。正常运行APP,找到3873,这个PID。

因为是arm指令的,所以要使用armeabi-v7a版本的来dump,首先通过maps文件来查找到so文件在内存中的地址分布。
1 | oriole:/data/local/tmp/build/local/armeabi-v7a # cat /proc/3873/maps | grep libDexHelper.so |
看到是e0702000-e07b2000。所以直接
1 | oriole:/data/local/tmp/build/local/armeabi-v7a # ./dump 3873 e0702000 e07b2000 ./libDexHelp_dump.so 0 1 |
将libDexHelp_dump.so文件pull出来就是dump下来并且修复好的so文件了。
0x02 寻找函数
众所周知国内的检测函数基本都是通过pthread_create来创建检测线程的,所以要bypass检测的话就是patch掉检测的线程就好了。但是怎么找到函数的调用地址是困难的,壳会检测是否有hook pthread_create函数,所有没有办法直接通过该方法来获取到偏移地址,求助之后,师傅说可以自己修改一份ROM,在pthread_create函数的源代码中,增加一个logcat的打印,这样不需要Hook也可以每次运行的时候获取到偏移地址。于是找师傅直接要到偏移地址(后续有精力了再编译自己的ROM吧)。
1 | normal find thread func offset libDexHelper.so 0xdc1b9645 226885 37645 |
那么就直接开始针对第一个地址37645的分析,找到该函数。

直接交叉引用,找到是谁调用了它。可以看到在0x2AE34处,调用了一次sub_37644,但是这里IDA针对这一段都是红色的,说明并没有识别成函数,需要我们手动的来处理一下。

大概找到0x2AC88的位置,一路选中所有的代码,选中到0x2AF70处。


按下键盘的P键,将这一段代码标记成函数。在IDA中就不显示成红色的了。

然后找到调用sub_37644函数的汇编代码的位置,F5对这段函数进行反编译。

即可看到这里存在函数sub_21F94(v445, 0, sub_37644, v8);看这个代码结构也能感觉到说sub_21F94其实就是pthread_create函数,但是可能是通过了dlsym函数的获取到函数指针从而直接调用的。

0x03 处理函数
这里存在两种手法一种是直接nop掉sub_21F94,但是这个手法非常的不优雅,并且这里其实是存在v10的返回值的,后续的函数执行还需要用到v10,那么就存在程序运行崩溃的风险,那么我们选择的是处理sub_37644函数。
1 | void __fastcall __noreturn sub_37644(unsigned __int8 *a1) |
在0x37698还有0x3769C这两个位置存在两个DCD的字符串,我们需要手工的处理一下。

选中一个使用快捷键U先设置为无意义字符串

然后选中了之后快捷键C,设置为代码。0x3769C也是这么操作。

最终这两个会被设置成如下样式。

这里来仔细分析一下sub_37644函数,首先执行了PUSH {R4-R7,LR}来保存堆栈信息,所以一定会存在对应的POP {R4-R7,PC}汇编指令来恢复现场,那么这个汇编也就是该函数的结尾了其实。不过可以看到IDA的汇编中并没有对应的汇编,不知道是不是反编译的问题,这里使用鸡爪来一起分析一下。跳转到0x47644的地址,因为鸡爪开始的地址是`0x10000所以对比IDA的地址要大对应的数值。和IDA一样的是最后这里一样有两个位置的无意义字符,需要手动处理。


最终会被处理成以下内容

于是处理完了之后就可以看到右边的伪代码中存在一个return了。对应到0x47782这个地址的汇编代码就是POP {R4-R7,PC}也就是函数的结尾。

那么我们现在确定了THUMB指令就是F0BD

如果我们将0x37646的位置修改成POP {R4-R7,PC}的话,之后的代码就根本不执行了,就相当于掏空了该函数。

0x04 frida脚本
1 | onLeave: function (retval) { |
这里编写的脚本是将这个位置的汇编替换成了9C E0,对应的汇编就是b #0x13c,具体的意思就是跳转以当前地址以下的0x13C的地址去。

那么现在的地址是0x37646 + 0x13C = 0x37782。也就是直接执行POPEQ {R4-R7,PC}

从而这样就可以绕过检测函数。
下载链接: