一个android样本的过保护
前段时间处理一个android样本,样本本身作用不大,但是加了保护,遂做一个过保护的记录
通过dex2jar将dex转为jar文件的时候发现无法成功,通过抛出的异常可知,此处MainActivity:onCreate函数在解析的时候出现了问题。
使用ida打开该dex文件,发现该函数确实进行了加密
搜索一遍ida可以发现同样被处理的函数还有SmsReceiver.onReceive,此处很容易就断定此处是样本对远控发送数据的处理端。
通过分析apk数据包,可以发现apk中存在libAPKProtect.so的so文件,此处即可推断该apk中解密的处理有可能存在于.so文件中。
通过ida附加该进程调试
此时报错,由此推断so文件中做了反调试保护。
因此我用通过ida对应用进行启动调试,在该so文件的jni函数中查看都进行了什么反调试。下图为刚加载进内存的so文件。
通过ida反编译该so文件可以知道在jni函数中进行了ptrace处理,如下图,此处只需要在调试的时候将此处的blx ptrace指令nop就行,这样就可以进行调试了。
在jni函数中,进行ptrace之后会继续向下执行,首先运行到函数sub_14ec
跟进该函数发现有进行dex字符的对比操作,通过调试发现r4寄存器中保存了加载到内存中的dex文件的地址,此处将该dex文件dump出来后发现此处还没有进行解密。
现在我们找到了内存中加载的dex文件,但是如何确实它在何时进行解密了?通常对so的解密都是在jni函数中完成的,因此,此处我们只要在jni函数的返回处下断,断下之后在进行内存dump即可,如下图即为解密之后的dex,此时SmsReceiver.onReceive已是正常的 smali代码。
对比加解密之后的两个dex即可发现,除去内存中的dex需要的一些标志位之外,两个dex文件最大的不同之处有两处,即为两个被加密处理的函数。
那此处的加密是如何实现的了?通过查看jni函数即可发现,在jni函数的返回处调用了函数sub_1438,该函数负责对dex中的代码进行解密还原。
跟进函数后,首先在调用函数sub_1290对dex进行校验
之后获取内存中的dex文件地址,此处的地址为52320000
计算出第一个需要解密的函数在dex中的偏移,此处为1A90
通过对比即可发现加解密之后的两个文件长确实是从19A0处开始不同的,解密前是classes,解密之后是classs。
之后调用mprotect设置内存访问权限
最后进行解密操作
取密钥第一位
取解密函数第一位
做xor操作
结果写回,此时变成12,和解密后的文件一致。
通过分析可以发现,在so中对于解密声明得有专门的结构,其中第一处为dex中需要解密的函数在dex中的偏移,第二处为解密的长度,第三处为使用的秘钥,所有的需要解密的函数以此结构声明成一个连续的数组,由于对应的解密数组中包含了硬编码的函数偏移,所以解密处理中无需对dex进行解析。
至此整个样本的加壳流程就分析完毕了,dex中加密的函数通过so文件中保存的解密数组做xor操作计算得出。

浙公网安备 33010602011771号