一个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操作计算得出。

posted @ 2015-05-08 14:25  goabout2  阅读(252)  评论(0)    收藏  举报