Android ProGuard 混淆代码详解

根据官网的注解:

ProGuard is a free Java class file shrinker, optimizer, obfuscator, and preverifier.

原文非常简洁,翻译过来也很容易明白,ProGuard 能对 Java 字节码文件进行压缩、优化、混淆和预验证。ProGuard 几个典型的用法就是:1. 缩减应用的大小;2. 移动设备优化代码; 3. 防止恶意反编译或者篡改程序。

ProGuard 相较于其他 Java 混淆器优势的地方在于

compact template-based configuration

fast

command-line tool with an optional graphical user interface

ProGuard 可以删除 Java 代码中无用的类、字段、方法和属性,并混淆代码 ,从而减小 APK 的大小,打包 apk 上线时,代码是一定要混淆的,有些情况下,部分代码是不能混淆的,否则就会导致程序功能不能正常运行

配置 ProGuard

ProGuard 四大功能的工作顺序是压缩->优化—>混淆—>预验证。

压缩:检测和删除项目中没有使用的类、字段、方法和属性。如果存在两个类互相调用,但项目实际上并没有使用到这两个类,这两个类也会被删除。

优化:优化代码的复杂调用,使代码运行顺序更为合理。

混淆:依据用户的配置,将代码的包名、类名、方法名和变量名等改成 a,b,c 等无意义的名称。Java 源代码编译后产生二进制 class 文件,这个 class 文件可以反编译成 Java 代码。反编译后生成的 Java 代码除了原来的注释外,其他代码比如变量名、类名和方法名等基本都能看到,和 Java 源代码几乎没有区别。为了防止项目代码被泄露,我们需要把项目代码中的包、类、方法和变量名等 Java 元素的名称改成无意义的名称。这个过程就是混淆。混淆之后的代码只是在一些名称上有修改,对代码的结构没有影响,所以混淆后的代码依然可以运行。项目经混淆后并不是说代码就不能被反编译了,只是反编译混淆后的项目后看到的代码将不是源码,变量名变得不再能一眼看懂其意思,此时想弄懂原有的项目代码架构很难。在混淆的过程中,不影响正常工作的信息将永久删除,使得反编译之后的代码变得更加难以理解。

预验证:在 Java 平台对处理后的代码进行预检,保证代码能够正常运行。这一步在 Android 项目中不需要。

Android Studio 已经集成了 ProGuard 工具。对 Android 项目进行混淆时,我们只需修改一些配置即可。 随便打开一个 Android 项目,在 app 目录下的 build.grade 文件中可以看到如下代码

buildTypes {    debug {        minifyEnabled false    }    release {        minifyEnabled true        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-project.txt'    }}

以上述代码为例,minifyEnabled 置为 true 表示在 release 环境下启用 ProGuard 工具。在打包程序时,这一项必须置为 true, 否则 release 打出的包将没有压缩、优化、混淆。

proguardFiles 命令后面的两个文件是 ProGuard 的配置文件,启用 ProGuard 后, ProGuard 对项目的处理将遵循这两个文件的配置。proguard-android.txt 是 Android Studio 集成 ProGuard 工具时自带的 ProGuard 配置文件,该文件在 Android SDK tools/proguard/ 目录下,proguard-rules.pro 是开发项目时由程序员添加的配置文件。

官网建议,为了更好地压缩代码,Android 还在SDK同目录中提供了 proguard-android-optimize.txt 文件,它包含了相同的规则,但是提供了额外针对 bytecode 的分析优化。而与此同时 proguard-android.txt 是不提供代码优化的。

proguard-rules.pro 文件可以在当前 Android 项目 app 目录下找到。初始时此文件是空白的,开发者可以在这个文件中添加自己项目的 ProGuard 配置,不要也不能在 proguard-android.txt 和 proguard-android-optimize.txt 中添加自定义规则。proguardFiles 后面可以加入多个文件名,意味着 ProGuard 工作会遵循多个文件的配置。

当在项目中配置了 minifyEnabled 为 true 时,如果不配置 ProGuard 文件,ProGuard 会混淆所有代码。而有些情况下,有些代码是不能混淆的,否则就会导致程序出错。常用的不能混淆的代码如下:

使用反射的地方

JNI 方法

系统接口(Framework 层下所有的类),Manifest 中声明的所有类,四大组件,Application 子类不混淆

xml 中声明的所有资源名

使用第三方开源库或者引用其他第三方的SDK包时,需要在混淆文件中加入对应的混淆规则

Parcelable的子类和Creator静态成员变量不混淆,否则会产生 Android.os.BadParcelableException 异常

使用GSON、fastjson等框架时,所写的JSON对象类不混淆,否则无法将JSON解析成对应的对象

有用到WebView 的 JS 调用也需要保证写的接口方法不混淆

Android Studio 启用 ProGuard 工具后,会默认不混淆系统接口、Manifest 中声明的所有类和 xml 中声明的所有资源名,因此这些情况下不需要手动配置 ProGuard 文件。而其他情况下不应该混淆的代码就需要对 ProGuard 文件进行配置。

常用的 ProGuard 配置语法

从给定的文件中读取配置参数

-include {filename}

保护给定的可选属性,例如 Exceptions,InnerClasses,Signature,Deprecated,SourceFile,LineNumberTable,Annotation,EnclosingMethod

-keepattributes Exceptions,InnerClasses,Signature,Deprecated,            SourceFile,LineNumberTable,*Annotation*,EnclosingMethod

例如,在代码中使用了反射,加入以下混淆规则:

-keepattributes Signature,EnclosingMethod

保护指定的类文件和类的成员(类中的方法和成员变量都是类的成员,下同)

-keep {Modifier} {class_specification}

例如,保护指定包下面的类:

-keep class info.einverne.jsonobject.** { *; }  // 不混淆 info.einverne.jsonobject 包下面类和所有类成员变量-keep class info.einverne.jsonobject.personinfo        // 不混淆具体类

保护指定类的成员

-keepclassmembers {modifier} {class_specification}

例如,保护继承了 Serializable 接口的类:

-keepclassmembers class * implements java.io.Serializable {    static final long serialVersionUID;    private static final java.io.ObjectStreamField[] serialPersistentFields;    private void writeObject(java.io.ObjectOutputStream);    private void readObject(java.io.ObjectInputStream);    java.lang.Object writeReplace();    java.lang.Object readResolve();}

或者,不混淆 enum 类:

-keepclassmembers enum * {    public static **[] values();    public static ** valueOf(Java.lang.String);}

保护指定的类和类的成员,但条件是所有指定的类和类成员是要存在。

-keepclasseswithmembers {class\_specification}

例如,不混淆 native 方法:

  -keepclasseswithmembernames class * {      native <methods>;  }

如果不在压缩步骤中删除,则保护指定的类和类的成员的名称

-keepnames {class\_specification}

如果不在压缩步骤中删除,保护指定的类的成员的名称

-keepclassmembernames {class\_specification}

如果不在压缩步骤中删除,保护指定的类和类的成员的名称

-keepclasseswithmembernames {class\_specification}

忽略警告,避免打包时某些警告出现

-ignorewarnings

是否使用大小写混合

-dontusemixedcaseclassnames

其他选项

-dontshrink    不压缩(不配的话默认是使用 ProGuard 的压缩功能)-dontoptimize    不优化(不配的话默认是使用 ProGuard 的优化功能)-dontobfuscate    不混淆(不配的话默认是使用 ProGuard 的混淆功能),需要注意 release 版本不要启用此选线-dontusemixedcaseclassnames    混淆时不会产生形形色色的类名

ProGuard 配置通配符

? 匹配除包分隔符外的任意单个字符*  匹配除包分隔符外的所有符号** 匹配多个字符(任意)%  匹配所有基本类型(不包含 void)***  匹配任何类型!  不匹配<init>  匹配所有构造函数<fields>  匹配所有字段<methods> 匹配所有方法

reference

https://developer.android.com/studio/build/shrink-code.html

完整的命令配置指南 http://proguard.sourceforge.net/index.html#manual/usage.html

https://github.com/D-clock/Doc/blob/master/Android/Gradle/3_ProGuard%E5%9F%BA%E7%A1%80%E8%AF%AD%E6%B3%95%E5%92%8C%E6%89%93%E5%8C%85%E9%85%8D%E7%BD%AE.md

Share

Related Posts

Android 反编译 - 02/22/2017

Android GPS 反作弊 - 11/24/2016

Android ProGuard - 11/15/2016

Android 过渡动画框架 - 10/21/2016

Android 提醒 - 10/11/2016

Android 使用自定义 keystore 调试 - 10/09/2016

Android 常见错误 - 09/29/2016

android 6 runtime permission - 09/27/2016

Android Snackbar 使用 - 09/26/2016

Android Notification - 09/25/2016

Android Animation Interpolator - 09/06/2016

Android ImageView ScaleType - 09/05/2016

Android Animation - 09/04/2016

国行 Moto 360 2代一周使用感受 - 08/13/2016

Android 人脸检测 - 08/06/2016

我使用的 Xposed module - 07/15/2016

Android lib Timber - 06/24/2016

Genymotion 安装 - 02/08/2016

扫描二维码在移动设备查看

← Previous(前一篇)

Archive(目录)

Next(后一篇) →

blog comments powered by Disqus

undefined --undefined

学习笔记 377

Android 26

Java 10

AndroidDev 18

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 196,099评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,473评论 2 373
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 143,229评论 0 325
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,570评论 1 267
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,427评论 5 358
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,335评论 1 273
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,737评论 3 386
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,392评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,693评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,730评论 2 312
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,512评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,349评论 3 314
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,750评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,017评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,290评论 1 251
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,706评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,904评论 2 335

推荐阅读更多精彩内容