您好,欢迎访问一九零五行业门户网

安卓APP逆向分析与保护机制是怎样的

想知道android app常见的保护方法及其对应的逆向分析方法吗?
在本次分享中,探讨了多个方面的安卓app安全,包括混淆代码、整体dex加固、拆分dex加固和虚拟机加固。这些内容已经成为国内近几年android app安全保护中的一个主要趋势。
一、混淆代码java代码是非常容易反编译的,作为一种跨平台的、解释型语言,java 源代码被编译成中间“字节码”存储于class文件中。由于需要跨平台,这些字节码中包含大量语义信息,容易被反编译成java源代码。开发人员通常会对编译好的class文件进行混淆以更好地保护java源代码。
混淆就是对发布出去的程序进行重新组织和处理,使得处理后的代码与处理前代码完成相同的功能,而混淆后的代码很难被反编译,即使反编译成功也很难得出程序的真正语义。proguard是一个开源项目,它能对字节码进行混淆、体积缩减和优化等处理。
proguard处理流程图如下所示,包含压缩、优化、混淆、预检四个主要环节:
压缩(shrink):检测并移除代码中无用的类、字段、方法和特性(attribute);
优化(optimize):对字节码进行优化,移除无用的指令。优化代码,非入口节点类会加上private/static/final,没有用到的参数会被删除,一些方法可能会变成内联代码;
混淆(obfuscate):使用a、b、c、d这样简短而无意义的名称,对类、字段和方法进行重命名;
预检(preveirfy):在java平台上对处理后的代码进行预检,确保加载的class文件是可执行的。
在分享中,钟亚平展示了利用proguard,对dex2jar进行反编译处理后的apk效果示例:
proguard处理后
proguard混淆器不仅能够保护代码,而且能够精简编译后的程序大小,减少内存占用。
混淆代码逆向分析钟亚平分享了一个名为deguadr的国外工具,它使用统计方法来解混淆代码,以便反编译。尽管这个工具的准确性不是100%,但它仍能部分地帮助反编译代码。
使用deguadr解混淆的示例:
com.xxxxx.common.util.cryptoutil网站也提供了一种反编译服务,如下所示:
java.lang.string a(byte[]) -> encodetostringjava.lang.string a(byte[],boolean,java.lang.string) -> a byte[] a(byte[],byte[]) -> encrypt byte[] b(byte[]) -> getkey byte[] b(byte[],byte[]) -> decrypt byte[] d(java.lang.string) -> getkey java.lang.string a(byte,char[]) -> a java.lang.string a(java.io.file) -> gethash java.lang.string a(java.lang.string) -> c java.lang.string b(java.lang.string) -> encode
二、整体dex加固随着安全技术的不断发展,新的“加固技术”已经出现,用以加强android的保护强度。dex加固是对dex文件进行加壳防护,防止被静态反编译工具破解而泄露源码,最刚开始出现的是整体加固技术方案。
整体加固技术的原理如上所示,包括替换application/classes.dex、解密/动态加载原classes.dex、调用原application相关方法、将原application对象/名称设置到系统内部相关变量四大环节。其中最为关键的一步就是解密/动态加载原classes.dex,通过加密编译好的最终dex源码文件,然后在一个新项目中用新项目的application启动来解密原项目代码并加载到内存中,再把当前进程替换为解密后的代码,能够很好地隐藏源码并防止直接性的反编译。
整体dex加固逆向分析整体dex加固逆向分析有两种常用的方法。其一是在内存中暴力搜索 dex\n035,再 dump。以下是在32位系统中的效果示例:
另一种方法就是通过hookdvmdexfileopenpartial(void* addr, int len, dvmdex**)。
三、拆分dex加固随着业务规模发展到一定程度,不断地加入新功能、添加新的类库,代码在急剧膨胀的同时,相应的apk包的大小也急剧增加,那么简单的整体加固方案就不能很好地满足安全需求,在整体加固方案之外又出现了拆分加固的技术方案。
但是如上所示,dex文件在加固时,针对中间缺失的一部分数据会以解密后的数据来替换,有的时候这种拆分替换也会导致数据不准确。需要了解dex文件的数据结构,才能确定应该拆分哪种类型的数据。
dex文件结构极为复杂,以下图示选取了其中较为重要的内容。事实上,dex文件是一个以class为核心组装起来的文件,其中最重要的是classdata和classcode两部分,有其特定的接口和指令数据,选取这两部分来拆分的话,即使拆分出来也不会泄露class数据和字节码数据,反编译出来也不完整,安全性较高。
拆分dex加固逆向分析对于dex拆分加固的逆向分析,如下所示,可以用classdata替换从而组装成新的dex文件,虽然和原来的dex文件不会完全一致,但也在一定程度上复原了被拆分数据的样子。
但要注意的是,这种方法仅适用于被拆分出去的数据变形一次性完成,也就是说,在有其他保护思路的情况下尽量避免使用,而且即使有需要也尽量选在用到这个类的时候才去恢复。
此外还有一个更底层一些的工具dexhunter,这个工具较为前卫,但同时也有一些局限性,譬如部分指令数据会被优化,形成的代码界面不是很美观等等。
四、虚拟机加固对字节进行处理是虚拟机加固的一种方式,也可看作是dex拆分加固的一种。下面是一个经过虚拟机加固处理的常规的android系统代码
以add-int v0, v1, v2、sub-int v0, v1, v2、mul-int v0, v1, v2这三条指令进行替换,然后进行加固编译,这样子操作后,即使把替换后的数据恢复了,也不会以add-int v0, v1, v2、sub-int v0, v1, v2、mul-int v0, v1, v2这三条指令进行替换,然后进行加固编译,这样子操作后,即使把替换后的数据恢复了,也不会变形成为之前的字节码,安全系数较高。
虚拟机加固逆向分析—hook jni 接口
这种方式下的逆向分析,一方面可以通过hook jni 接口来实现,它有两种实现方式。
其一是类成员/静态变量操作相关接口,比如:
getstaticdoublefieldsetstaticdoublefield getdoublefield setdoublefield … 
(byte, object, int,long…)
其二是反射调用类方法,比如:
callvoidmethodacallbooleanmethoda callshortmethoda callobjectmethoda …
callstaticvoidmethodacallstaticbooleanmethoda callstaticshortmethoda callstaticobjectmethoda …
(byte, int, long,double …)
callobjectmethoda(jnienv* env, jobject object, jmethoid method, …)
通过hookjni 接口实现虚拟机加固逆向分析
使用hook jni接口可以了解app大致的调用流程,无需进行底层逆向。但是对于复杂的调用过程,或者虚拟化方法数量较多的情况,这种逆向分析手段看起来会比较混乱;对于不需要返射到java层执行的指令,如算术、逻辑运算等,则无法监控到。
虚拟机加固逆向分析—分析指令操作码映射另一方面,也可以通过分析指令操作码映射来逆向分析。以下方法可以在使用相同加固版本或映射关系的情况下采用:
但在实际情况中,每次加固时的映射关系都是随机变化的,如下所示,这种情况下就无法直接建立映射关系。
不依赖于操作码的映射关系只与虚拟机结构有关,所以需要根据偏移关系建立映射关系,从而进行逆向分析。
以上就是安卓app逆向分析与保护机制是怎样的的详细内容。
其它类似信息

推荐信息