代码混淆

Android开发除了部分功能采用C/C++编码外,其余主要都是采用Java进行编码开发功能。Java应用非常容易被反编译,Android自然也不例外。只要利用apktool等类似的反编译工具,就可以通过安装包获取源代码。Google为了保护开发者的知识产权,为Android提供了ProGuard混淆方案,以增加反编译后源码阅读,但对于Android开发老司机和逆向工程师来说,解读还原出源代码只是时间问题。

ProGuard是针对Java应用的保护,并不是专门针对Android应用的,Android虽然使用Java开发,但是毕竟不是跑在JVM上,所以安装包结构和普通的Java应用还是区别多多。如果你对免费的ProGuard放心不下,可考虑试试付费的混淆方案DexGuard,除了拥有ProGuard的功能外,还包含资源混淆,字符串加密,类加密和dex文件分割等。

虽然代码混淆是最为基础的保护措施,不过国内仍有不少应用还是裸奔的,其中还包括一些大厂应用(此处不表)。

签名校验

Android黑产里面,有一个叫做二次打包,也称为重打包。即通过反编译正版应用后,可以获得smali源码,往其中注入代码或者修改相应业务逻辑后,再利用新的签名进行重新打包,并发布到应用市场去,很多无良开发者就是通过这种方式去破解一些付费应用或者往其中注入广告代码来获利。简单梳理一下重打包的基本流程:

  1. 对正版应用用apktool类逆向工具进行解包;
  2. 在某处地方注入smali代码;
  3. 利用IDE生成签名文件,再通过jarsigner进行签名;
  4. 上传应用市场;

为了与二次打包做对抗,可以在应用内的关键功能入口增加校验签名的检测,如果发现应用签名非正版,则强制关闭应用或者限制用户使用。加签名校验代码时,可以考虑:

  1. 在JNI层中加校验代码,相比在Java层的代码,JNI层的逆向难度更大;
  2. 如果要在Java层加校验代码,不要在一个地方暴露一段长串字符串,对于逆向工程师是来说,这是非常明显的提示。可以考虑将字符串打散存放在各处,这样会增加破解分析的难度;

当然,不要以为放在JNI就高枕无忧,对于JNI层,同样可以进行代码注入,来暴力破解你签名校验的逻辑,只不过相比Java层的,JNI层所需成本更高,这样也就能拦截掉一部分逆向人员的歪主意。

加壳

加壳的原理是通过加密原应用的安装包中的dex文件,其主要操作方式大致如下:

  1. 准备要进行加壳的原应用安装包(以下简称原apk)、用于做壳的安装包(以下简称壳apk);
  2. 对原Apk进行拆解获取各个部分,并将dex文件进行算法加密(以下简称加密原dex);
  3. 将加密原dex和壳Apk中的dex进行组合,合并成为新的dex文件;
  4. 利用特制的打包工具合并生成加密后的apk;

这种通过隐藏dex文件的方式加壳方式,最终是利用ClassLoader在内存中解密并进行动态加载运行。而如果是修改dex文件的加壳方式,其主要是抽取DexCode中的字节码指令后用零去填充,或者修改方法属性等操作,其修复时机则是运行时在内存中做相应的修正工作。

通过加壳得到的安装包如果不进行脱壳操作,逆向人员就无法拿到真正的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和数据库中的重要信息;

资源保护

资源保护同样可以提高逆向分析的难度,但个人觉得只对逆向小白有效,可以考虑引入试试,目前比较知名的方案就是微信和美团两家的了,具体参见:

总结

应用安全的攻防就是这么一个相爱相杀又相辅相成的过程,对于客户端能做到的安全防范也是有限的,更多的还是应该结合后台业务分析来实现相应的对抗机制,对于中小企业而言,没有专门的安全人员去研究对抗方案,选择市面上成熟的加固方案是一个不错的选择。而对于大企业来说,内部早已有了自己的安全中心,自然也有自己的一系列对抗方案,包括在后端生成每个用户的画像来判别用户类型等等。大致就是这么些了,文末附上一些不错的资料,希望本文能对你有所启发!

Android 应用安全风险与防范的更多相关文章

  1. 掘金 Android 文章精选合集

    掘金 Android 文章精选合集 掘金官方 关注 2017.07.10 16:42* 字数 175276 阅读 50053评论 13喜欢 669 用两张图告诉你,为什么你的 App 会卡顿? - A ...

  2. Android 应用防止被二次打包指南

    前言 “Android APP二次打包”则是盗版正规Android APP,破解后植入恶意代码重新打包.不管从性能.用户体验.外观它都跟正规APP一模一样但是背后它确悄悄运行着可怕的程序,它会在不知不 ...

  3. 一个五年 Android 开发者百度、阿里、聚美、映客的面试心经

    花絮 也许会有人感叹某些人的运气比较好,但是他们不曾知道对方吃过多少苦,受过多少委屈.某些时候就是需要我们用心去发现突破点,然后顺势而上,抓住机遇,那么你将会走向另外一条大道,成就另外一个全新的自我. ...

  4. 《Android底层接口与驱动开发技术详解》digest

    第一章:IDE:Eclipse ADT for java developer其它: Apache Ant Java SE Development Kit5或6 Linux和Mac上使用Apache A ...

  5. Android安全防护防护———加密算法

    摘要 这篇文章本来早就应该写了,但是由于项目一直开发新的需求,就拖后了.现在有时间了,必须得写了.现在Android应用程序对安全防范这方面要求越来越高了.特别是金融行业,如果金融app没有没有做好相 ...

  6. 如何进入百度、阿里,一个6年Android老司机的面经

    花絮 也许会有人感叹某些人的运气比较好,但是他们不曾知道对方吃过多少苦,受过多少委屈.某些时候就是需要我们用心去发现突破点,然后顺势而上,抓住机遇,那么你将会走向另外一条大道,成就另外一个全新的自我. ...

  7. 《DNS攻击防范科普系列3》 -如何保障 DNS 操作安全

    引言 前两讲我们介绍了 DNS 相关的攻击类型,以及针对 DDoS 攻击的防范措施.这些都是更底层的知识,有同学就来问能否讲讲和我们的日常操作相关的知识点,今天我们就来说说和我们日常 DNS 操作相关 ...

  8. 只想着一直调用一直爽, 那API凭证泄漏风险如何破?

    如今各家云厂商都通过给用户提供API调用的方式来实现一些自动化编排方面的需求.为了解决调用API过程中的通信加密和身份认证问题,大多数云厂商会使用同一套技术方案—基于非对称密钥算法的鉴权密钥对,这里的 ...

  9. 【流量劫持】SSLStrip 的未来 —— HTTPS 前端劫持

    前言 在之前介绍的流量劫持文章里,曾提到一种『HTTPS 向下降级』的方案 -- 将页面中的 HTTPS 超链接全都替换成 HTTP 版本,让用户始终以明文的形式进行通信. 看到这,也许大家都会想到一 ...

随机推荐

  1. Docker(二十一)-Docker Swarm集群部署

    介绍 Swarm 在 Docker 1.12 版本之前属于一个独立的项目,在 Docker 1.12 版本发布之后,该项目合并到了 Docker 中,成为 Docker 的一个子命令.目前,Swarm ...

  2. Js单元测试工具 以及 粗浅的对我的快乐运算进行测试

    1. Karma的介绍 Karma是Testacular的新名字,在2012年google开源了Testacular,2013年Testacular改名为Karma.Karma是一个让人感到非常神秘的 ...

  3. 统计nginx日志的状态码

    日志格式 61.159.140.123 - - [23/Aug/2014:00:01:42 +0800] "GET /favicon.ico HTTP/1.1" 404 \ &qu ...

  4. python 按照固定长度分割字符串

    >>> import re >>> string = '123456789abcdefg' >>> re.findall(r'.{3}', str ...

  5. word 里面没输入法

    文件,选项,高级,输入法控制处于活动状态   ,有勾选就去掉,无勾选就勾上,确定后重开word即可

  6. 洛谷P4219 [BJOI2014]大融合(LCT)

    LCT维护子树信息的思路总结与其它问题详见我的LCT总结 思路分析 动态连边,LCT题目跑不了了.然而这题又有点奇特的地方. 我们分析一下,查询操作就是要让我们求出砍断这条边后,x和y各自子树大小的乘 ...

  7. Winform Treeview 的按需加载

    最近项目里用到treeview,原先设计的是一开始就把所有数据都加载到treeview里,后来发现客户的数据量实在太大,加载所有数据要2分钟,这个是客户没法接受的.后来就考虑到用户也不是一开始就要看所 ...

  8. word 大纲-目录

  9. Elasticsearch 5.0 安装 Search Guard 5 插件

    一.Search Guard 简介 Search Guard  是 Elasticsearch 的安全插件.它为后端系统(如LDAP或Kerberos)提供身份验证和授权,并向Elasticsearc ...

  10. java基础基础总结----- Date

    前言:其实在学习这个的时候,自我感觉学到什么直接查询API就可以了,没有必要再去研究某个方法怎么使用, 重点学习一下经常用到的方法.感觉自己的写的博客,就跟自己的笔记一样,用的是时候,就能快速的查找 ...