在阿里云云栖社区举办的在线培训中,来自阿里移动安全部的陵轩带来了题为《APP加固新方向——混淆和瘦身》的精彩分享。本次分享的主要内容包括APP加固的发展历程以及阿里内部对移动安全加固最新的研究——混淆和APK优化瘦身。

直播回顾视频:https://yq.aliyun.com/edu/lesson/play/393

以下内容是根据直播和PPT整理。


加固的意义

从安卓2.x版本起,加固技术就逐渐火了起来。最初,只有一些创业型公司涉及加固领域;随着安卓应用的逐渐升温,诸如阿里、腾讯、百度等大型互联网公司逐渐涉及该领域。

那么为什么要对APP进行加固呢?主要原因有三点:首先安卓的APP应用通常采用Java语言编写的,开发门槛低,容易被反编译(解释性语言的弊端);其次安卓市场比较混乱且可自签名,进而导致大量应用被二次打包,植入广告、木马;同时,手机Root后,黑客可利用Hook等技术手段可对应用进行动态攻击,获取应用的核心逻辑。综合这三点来看,安卓应用的安全系数是非常低的,因此APP加固就有了意义:应用加固之后可以有效减少反编译、二次打包、植入广告木马等操作。

传统加固

第一代加固技术采用的是Dex加密存储,解密时落地;落地之后通过自定义的DexClassLoader将解密出的Dex加载到内存中,然后程序运行该文件(Dex是APK的Java代码经过编译后生成的文件,可以简单理解为Java的逻辑)。

其脱壳方式很简单:因为Dex加密是整体进行的,解密时还会落地。可以通过HOOK文件操作(Read、Write、Delete)将Dex文件脱壳出来,通过反编译工具分析,从而得到APP的核心逻辑。

之后对第一代版本进行了升级,与未升级版相比:Dex加密存储方式相同,但解密时不落地;解密之后在内存中通过自定义DexClassLoader进行加载。升级版本的脱壳方法也比较简单,主要采用内存Dump方法,将文件写到磁盘中,通过HOOK dvmDexFilePartial的方式达到脱壳目的。

第二代加固方式采用的是Dex Method方法抽离,Dex在内存中加载时不连续。其原理是:Method方法通过一些加固方法抽离,APK在运行时,整个Dex会一并修复,然后在内存中运行,也就说在内存中有着完整的Dex代码。第三代方式与第二代相比同样是采用Dex Method方法抽离,但Dex执行中动态解密。两者的差异在于:后者在APK运行时,Dex文件是不进行修复的,而是等到Class被执行时才进行解密。

对第二代和第三代进行脱壳前,需要先了解Dex结构。Dex结构从dex_header开始,在头部存在Dex的标志位;然后逐步按结构指向Method结构体,Method结构中的code_off字段最终指向可执行代码。因此在第二代和第三代的脱壳过程中,需要HOOK DVM虚拟机中很底层的函数,从而拿到需要执行的APK的类,进而得知Class object全部方法;然后在内存中对DEX进行重建,重建之后再将其Dump到本地,得到脱壳之后的Dex文件,便于后续采用工具分析。

除了上述的脱壳方式之外,通用的脱壳机(开源的Zjdroid、DexHunter)也可以轻松脱掉大部分壳;并且,由于传统的加固方式容易被脱壳,导致目前脱壳类教程非常之多。因此,传统的加固方式面临着很大的挑战。

全量混淆

针对层出不穷的脱壳方式。阿里内部经过多次讨论后,认为传统的加固方式已过时,需要转变思路:混淆。

ProGuard混淆

在APP发布前,通常会对应用进行ProGuard混淆,类似上图的配置。图中的proguard-android.txt/proguard-rules.pro是ProGuard的混淆规则。在Java中,某些特性如反射调用以及可序列化类等是需要保留的,因此需要人工配置一些复杂的规则。当规则全部配置成功后,对APK进行反编译,从上图可以看到某些逻辑被混淆成了a、b、c等,进而大大增加了黑客逆向分析的难度。

通过混淆可以增加逆向分析的难度,但并不代表着不能分析。上图是对金山隐私保险箱逆向分析的案例,通过反编译工具分析,得知金山隐私保险箱对其核心代码进行了混淆,例如它的类名是a、b、c等形式。由于ProGuard混淆时需要配置很多规则,很多开发人员为了保障兼容性会保持很多类,导致APK内的逻辑并不全部混淆,进而导致安全性的降低,通常ProGuard混淆率在10%-30%。

为了解决ProGuard混淆需要配置很多规则导致混淆效率低下的问题,阿里内部研发了全量混淆技术。上图左侧是手淘在未混淆之前的反编译情况,其中的类、函数名都是一目了然的;经过全量混淆之后的效果图如右侧所示:类名全部变成了a、b、c的类型,并且全量混淆几乎是不用任何配置的,大大降低了使用成本。目前,全量混淆已在线上对外发布。

优化瘦身

随着APK功能的增加,其体积也在不断地增大,例如手淘、支付宝等应用达到五十几兆、游戏类的APK达到几百甚至上千兆,进而引发了手机资源存储、用户下载流量浪费等问题。因此APK优化瘦身势在必行。

APK优化瘦身的实现逻辑主要包括:首先,清除Dex文件Debug信息,减少编译器自动产生函数,优化性能,减少体积;其次,通过Java层拦截技术,对SO进行重新打包压缩,减少体积;同时,修改Android应用资源名称,通常资源名称是带有实际意义的,通过将带有实际意义的长文件名修改成上文所示的a、b、c等形式既减少应用体积,又提高了资源保护强度;此外,通过自行开发的7z工具,对签名后的APK包重新压缩,达到进一步减少体积的目的。

上图是阿里内部应用优化瘦身之后对比效果图,从图中可以看到手淘、支付宝、钉钉瘦身前后的对比,瘦身效果可以达到10%左右。

上图是市场上常见应用瘦身前后的对照表,微博、百度地图等应用优化后的减少百分比可达到百分之十几;华为账号等应用优化瘦身减少率甚至达到40+%。通常应用优化瘦身减少率在15%-20%,具体数值和APK的开发质量有关。

总结

全量混淆和优化瘦身等阿里内部使用的加固方案都是在实际业务强需求下开发的,经历了数以万计的APP和用户测试,其稳定性和可靠性绝对具有保障。

APP加固新方向——混淆和瘦身相关推荐

  1. 业界新闻: JAVA 7新特性让JVM“瘦身”成功!

    很多用户一直以来都有一个需求:希望一个简单的JVM,只装载他们需要的东西,比如简单的Applet.而通常JVM都是很大,15mb以上.所以这些用户希望能够减少JVM的大小. 目前,Java 7通过了一 ...

  2. 安卓app启动速度优化,Android-APP-终极瘦身指南

    前言 APK瘦身即是对APK大小进行压缩策略,减小APK安装包大小,更小的安装包更有助于吸引用户安装:虽然说APK瘦身对于Android对应用可分配内存的限制影响不大,但是还是有一些影响的. 最近几周 ...

  3. Maven项目混淆、瘦身、打包exe

    项目混淆 ProGuard 是一个混淆代码的开源项目,它的主要作用是混淆代码,ProGuard 包括以下 4 个功能: 压缩(Shrink):检测并移除代码中无用的类.字段.方法和特性(Attribu ...

  4. YoMail新版发布会:YoMail+石墨文档+坚果云,重新定义Email APP发展新方向

    软件名称: YoMail for Mac(邮箱客户端) 软件版本:  V1.7 软件大小:  17.5 MB 授权方式: 免费软件 软件下载地址: www.yomail.com/news/YoMail ...

  5. 运动瘦身动作识别APP开发

    无论是基于国家政策还是个人要求,我们都越来越重视体育健身.此外,随着经济社会的发展,中国人民对体育健身的要求正在从欣赏转向参与"全员运动"政策出台以来,人们从政策出台到现在,人们从 ...

  6. iOS 优化 - 瘦身

    前言 iOS 优化将是一个专题,其中会包括包体积优化(瘦身).启动时间优化.UI 优化等等.那么这个专题的开篇就从瘦身开始吧. APP 的大小是分为 APP 下载大小和安装大小两个概念的. 下载大小是 ...

  7. PP-OCR: 3.5M超轻量中英文OCR模型详解(四) 文本识别优化瘦身策略

    PP-OCR: A Practical Ultra Lightweight OCR System 论文地址:https://arxiv.org/abs/2009.09941 代码地址:https:// ...

  8. 图片瘦身的正确姿势,让你的 CDN 费用省 50% 以上!

    七牛云新推出的图片瘦身功能是做什么的? 打开七牛云的「数据处理」中的「图片瘦身」功能,在图片受到访问时,能够实时对图片进行瘦身,在保证分辨率和画质不变的情况下,可以将图片最高缩小 80%. 当「图片瘦 ...

  9. 让你的 CDN 费用省 50% 以上!图片瘦身的正确姿势

    七牛云新推出的图片瘦身功能是做什么的? 打开七牛云的「数据处理」中的「图片瘦身」功能,在图片受到访问时,能够实时对图片进行瘦身,在保证分辨率和画质不变的情况下,可以将图片最高缩小 80%. 当「图片瘦 ...

  10. 知物由学 | APP大瘦身,新一代AAB框架下的安全加固之道

    在 Google I/O 大会上,Google 向 Android 引入了新 APP 动态化框架 Android APP Bundle (AAB),被看作是对 Android 未来发展具有颠覆性的动态 ...

最新文章

  1. java list键值_java基础之对List,Map,Set等集合键值对的简单认识
  2. TCP/IP详解--第十八章
  3. pycharm专业版(window)安装
  4. when is completed field filled in the backend
  5. python pca降维_机器学习之sklearn中的降维算法
  6. python 元组是什么_python元组是什么?python元组的用法介绍
  7. clustered和nonclustered索引的区别
  8. 花了 2 元,用 1 根网线发起攻击,控制上千人
  9. Silverlight学习笔记1:浏览器外运行(Out Of Browser)及更新检查
  10. C++模拟斗地主发牌
  11. 2019年保研夏令营时间经验汇总
  12. html中竖线怎么写,网页中竖线的几种做法
  13. centos gcc卸载_CentOS gcc多版本的卸载与修复
  14. java 位运算取8位_5巨星生涯全明星队友:乔丹2位,科比8位,那詹姆斯呢?
  15. 炸裂!前浪老狗工作这5年遇到的面试题们,建议老铁们收藏研读
  16. 【Data URL】【RE】【bugku】逆向入门writeup
  17. 小度智能音箱维修点_小度音箱客服电话
  18. AK7739手册解读
  19. Arduino的数字信号、模拟信号以及串口整理
  20. vue实现登录时的图片验证码(纯前端)

热门文章

  1. 开源硬件的舞者--WIZnet
  2. Shell的解释和一些用法
  3. Halcon——颜色检测
  4. 《精进:如何成为一个很厉害的人》读后感
  5. 2020厦大计算机专硕分数,2020考研初试,你得考多少分才能上厦大?
  6. 从函数型数据到光滑函数
  7. 九枝兰专访-----深入解读程序化购买以及行业现状(初篇)
  8. 查看服务器的并发访问量以及访问的IP地址
  9. 定义类Shape作为父类,并在类中定义方法求周长和面积; (2)定义Shape子类圆形(circle),具有半径属性和常量PI,同时重写父类中的方法; (3)定义Shape子类长方形(rect
  10. 使用宏定义求圆的周长,面积