加入收藏 | 设为首页 | 会员中心 | 我要投稿 核心网 (https://www.hxwgxz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 业界 > 正文

请你吃一顿史上最全的Android混淆大餐

发布时间:2019-08-23 19:10:10 所属栏目:业界 来源:hardwork
导读:在 Android 日常开发过程中,混淆是我们开发 App 的一项必不可少的技能。只要是我们亲身经历过 App 打包上线的过程,或多或少都需要了解一些代码混淆的基本操作。那么,混淆到底是什么?它的好处有哪些?具体效果如何?别急,下面我们来一一探索它的独特魅力
副标题[/!--empirenews.page--]

在 Android 日常开发过程中,混淆是我们开发 App 的一项必不可少的技能。只要是我们亲身经历过 App 打包上线的过程,或多或少都需要了解一些代码混淆的基本操作。那么,混淆到底是什么?它的好处有哪些?具体效果如何?别急,下面我们来一一探索它的"独特"魅力。

混淆简介

代码混淆(Obfuscated code)是将程序中的代码以某种规则转换为难以阅读和理解的代码的一种行为。

混淆的好处

混淆的好处就是它的目的:令 APK 难以被逆向工程,即很大程度上增加反编译的成本。此外,Android 当中的"混淆"还能够在打包时移除无用资源,显著减少 APK 体积。最后,还能以变通方式避免 Android 中常见的 64k 方法数引用的限制。

我们先来看一下混淆前后的 APK 结构对比:

请你吃一顿史上最全的Android混淆大餐

请你吃一顿史上最全的Android混淆大餐

从上面两张图可以看出:经过混淆处理之后,我们的 APK 中包名、类名、成员名等都被替换为随机、无意义的名称,增加了代码阅读和理解的困难程度,提高了反编译的成本。细心的小伙伴可能又会注意到:混淆前后 APK 的体积竟然从 2.7M 减小到了 1.4M,体积缩减了近一倍!真的有这么神奇吗?哈哈,确实是这么神奇,让我们慢慢来揭开它的神秘面纱吧。

Android 当中的混淆

在 Android 中,我们平常所说的"混淆"其实有两层意思,一个是 Java 代码的混淆,另外一个是资源的压缩。其实这两者之间并没有什么关联,只不过习惯性地放在一起来使用。那么,说了这么多,Android 平台上到底该如何开启混淆呢?

启用混淆

  1. ...... 
  2. android { 
  3.  buildTypes { 
  4.  release { 
  5.  minifyEnabled true 
  6.  shrinkResources true 
  7.  proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 
  8.  } 
  9.  } 

以上就是开启混淆的基本操作了,通过 minifyEnabled 设置为 true 来开启混淆。同时,可以设置 shrinkResources 为 true 来开启资源的压缩。不难看出,我们一般在打 release 包时才启用混淆,因为混淆会增加额外的编译时间,所以不建议在 debug 模式下启用。此外,需要注意的是:只有在启用混淆的前提下开启资源压缩才会有效!以上代码中的 proguard-android.txt 表示 Android 系统为我们提供的默认混淆规则文件,而 proguard-rules.pro则是我们想要自定义的混淆规则,至于如何自定义混淆规则我们将在接下来会讲到。

代码混淆

其实,Java 平台为我们提供了 Proguard 混淆工具来帮助我们快速地对代码进行混淆。根据 Java 官方介绍,Proguard 对应的具体中文定义如下:

  • 它是一个包含代码文件压缩、优化、混淆和校验等功能的工具
  • 它能够检测并删除无用的类、变量、方法和属性
  • 它能够优化字节码并删除未使用的指令
  • 它能够将类、变量和方法的名字重命名为无意义的名称从而达到混淆效果
  • 最后,它还会校验处理后的代码,主要针对 Java 6 及以上版本和 Java ME

资源压缩

Android 中,编译器为我们提供了另外一项强大的功能:资源的压缩。资源压缩能够帮助我们移除项目及依赖仓库中未使用到的资源,有效地降低了apk包的大小。由于资源压缩与代码混淆是协同工作,所以,如果需要开启资源的压缩,切记要先开启代码混淆,否则会出现以下问题:

  1. ERROR: Removing unused resources requires unused code shrinking to be turned on. See http://d.android.com/r/tools/shrink-resources.html for more information. 
  2. Affected Modules: app 

自定义要保留的资源

当我们开启了资源压缩之后,系统会默认替我们移除所有未使用的资源,假如我们需要保留某些特定的资源,可以在我们项目中创建一个被 标记的 XML 文件(如 res/raw/keep.xml),并在 tools:keep 属性中指定每个要保留的资源,在 tools:discard 属性中指定每个要舍弃的资源。这两个属性都接受逗号分隔的资源名称列表。同样,我们可以使用字符 * 作为通配符。如:

  1. <?xml version="1.0" encoding="utf-8"?> 
  2. <resources xmlns:tools="http://schemas.android.com/tools" 
  3.  tools:keep="@layout/activity_video*,@layout/dialog_update_v2" 
  4.  tools:discard="@layout/unused_layout,@drawable/unused_selector" /> 

启用严格检查模式

正常情况下,资源压缩器可准确判定系统是否使用了资源。不过,如果您的代码(包含库)调用 Resources.getIdentifier(),这就表示您的代码将根据动态生成的字符串查询资源名称。这时,资源压缩器会采取防御性行为,将所有具有匹配名称格式的资源标记为可能已使用,无法移除。例如,以下代码会使所有带 img_ 前缀的资源标记为已使用:

  1. String name = String.format("img_%1d", angle + 1); 
  2. res = getResources().getIdentifier(name, "drawable", getPackageName()); 

这时,我可以开启资源的严格审查模式,只会保留确定已使用的资源。

移除备用资源

(编辑:核心网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读