【Android 应用安全风险与防范】我自横刀向天笑,去留肝胆两昆仑。这篇文章主要讲述Android 应用安全风险与防范相关的知识,希望能为你提供帮助。
代码混淆android开发除了部分功能采用C/C++编码外,其余主要都是采用java进行编码开发功能。Java应用非常容易被反编译,Android自然也不例外。只要利用apktool等类似的反编译工具,就可以通过安装包获取源代码。Google为了保护开发者的知识产权,为Android提供了ProGuard混淆方案,以增加反编译后源码阅读,但对于Android开发老司机和逆向工程师来说,解读还原出源代码只是时间问题。
ProGuard是针对Java应用的保护,并不是专门针对Android应用的,Android虽然使用Java开发,但是毕竟不是跑在JVM上,所以安装包结构和普通的Java应用还是区别多多。如果你对免费的ProGuard放心不下,可考虑试试付费的混淆方案DexGuard,除了拥有ProGuard的功能外,还包含资源混淆,字符串加密,类加密和dex文件分割等。
- 关于ProGuard,详见:https://www.guardsquare.com/en/proguard
- 关于DexGuard,详见:https://www.guardsquare.com/en/dexguard
- 关于反编译工具,详见我一篇旧文:那些值得你试试的Android竞品分析工具
签名校验Android黑产里面,有一个叫做二次打包,也称为重打包。即通过反编译正版应用后,可以获得smali源码,往其中注入代码或者修改相应业务逻辑后,再利用新的签名进行重新打包,并发布到应用市场去,很多无良开发者就是通过这种方式去破解一些付费应用或者往其中注入广告代码来获利。简单梳理一下重打包的基本流程:
- 对正版应用用apktool类逆向工具进行解包;
- 在某处地方注入smali代码;
- 利用IDE生成签名文件,再通过jarsigner进行签名;
- 上传应用市场;
- 在JNI层中加校验代码,相比在Java层的代码,JNI层的逆向难度更大;
- 如果要在Java层加校验代码,不要在一个地方暴露一段长串字符串,对于逆向工程师是来说,这是非常明显的提示。可以考虑将字符串打散存放在各处,这样会增加破解分析的难度;
加壳加壳的原理是通过加密原应用的安装包中的dex文件,其主要操作方式大致如下:
- 准备要进行加壳的原应用安装包(以下简称原apk)、用于做壳的安装包(以下简称壳apk);
- 对原Apk进行拆解获取各个部分,并将dex文件进行算法加密(以下简称加密原dex);
- 将加密原dex和壳Apk中的dex进行组合,合并成为新的dex文件;
- 利用特制的打包工具合并生成加密后的apk;
通过加壳得到的安装包如果不进行脱壳操作,逆向人员就无法拿到真正的dex文件,也就无从分析。这里可以看看使用360加固的一个应用的结构在没脱壳前的安装包结构
文章图片
只有寥寥几个类,而正真的安装包中的dex文件则被藏起来了,这进一步加大了逆向的难度。关于加壳,市面上已经有很多成熟企业加固方案可以使用,如梆梆安全、爱加密、360加固保等,如果不是专门研究这块的开发者去自行开发一套加壳方案,显然不太现实。
加壳也只是提高被逆向的门槛,对于功力不够的逆向开发者而言,只能就此作罢,而对于逆向老鸟来说,脱壳同样这是外包时间问题罢了。此外,对应用加壳还要留意平台兼容性问题,如此前某著名加固产品就出现过在ART虚拟机不兼容问题,以及将会影响项目使用某些热修复技术。
反动态调试你是不是曾以为没有拿到源代码就不可以调试Android应用了?然而并不是,只要反编译后拿到smali代码工程,再加上smalidea调试神奇,分分钟在Android Studio调试应用给你看,具体操作并不复杂,可以参照我文末提供的资料。即使你把核心代码放到了JNI层,我也可以祭出神器IDA Pro继续调试给你看,更何况,实际开发中能放进JNI层实现的核心代码实在有限。
为了对抗动态调试,可以考虑在源码中随意穿插相关的检测代码,在检测到动态调试时,直接进程自杀,异常退出虚拟机,大致实现如下:
/**
* 检测动态调试
*/
public void detectedDynamicDebug(){
if (!BuildConfig.DEBUG){
if (Debug.isDebuggerConnected()){
//进程自杀
int myPid = android.os.Process.myPid();
android.os.Process.killProcess(myPid);
//异常退出虚拟机
System.exit(1);
}
}
}
以上只是一个简单的例子,市面上很多加固产品做了更多的动态调试对抗措施。
数据保护数据保护这个主要例举以下几点:
- 不要在客户的存放登录密码(即使你加密了),最好采用token的形式;
- 数据传输记得加密;
- 重要数据存放内置存储中,不要存放在外置存储;
- 加密存放在xml和数据库中的重要信息;
- 安装包立减1M--微信Android资源混淆打包工具
- 美团Android资源混淆保护实践
推荐阅读
- mac 上如何安装非app store上的下载的软件-------打开未知来源
- Android监听home键
- Android DecorView浅析
- 从adb prrmission denied到理解android手机提权背后
- Android--SQLite应用
- 得到application
- 手机App调试(Android)
- WebApp框架
- Ubuntu 12.0432位eclipseandroidSDKNDK开发环境搭建