Android开发之代码混淆

应用混淆(ProGuard)

ProGuard是一个免费的JAVA类文件压缩,优化,混淆器。

它探测并删除没有使用的类,字段,方法和属性,它删除没有用的说明并使用字节码得到最大优化,它使用无意义的名字重命名类,字段和方法。

我们先来介绍下ProGuard

我们为啥要使用ProGuard?

  • 优化应用:创建紧凑的代码文档是为了更快的网络传输,快速装载和更小的内存占用;
  • 防止反向:创建的程序和程序库很难使用反向工程;
  • 预处理应用:充分利用JAVA的快捷加载的优点来提前检测和返回JAVA中存在的类文件。

有些什么参数可用?

  • -include {filename} 从指定的文件中读取配置参数
  • -basedirectory {directoryname} 指定基础目录为以后相对的档案文件
  • -injars {class_path} 指定要处理的应用程序jar,war,ear的目录
  • -outjars {class_path} 指定处理完后要输出的jar,war,ear目录的名称
  • -libraryjars {class_path} 指定要处理的应用程序jar,war,ear和目录所需要的程序库文件
  • dontskipnonpubliclibraryclasses 指定不去忽略非公共的库类
  • dontskipnonpubliclibraryclassmebmbers 指定不去忽略可见的库类的成员

上面提到了Jar、war、ear三种文件
Jar、war、ear、在文件结构上,三者并没有什么不同,它们都采用zip或jar档案文件压缩格式。但是它们的使用目的有所区别:
Jar文件(扩展名为. Jar,Java Application Archive)包含Java类的普通库、资源(resources)、辅助文件(auxiliary files)等。

War文件(扩展名为.War,Web Application Archive)包含全部Web应用程序。在这种情形下,一个Web应用程序被定义为单独的一组文件、类和资源,用户可以对jar文件进行封装,并把它作为小型服务程序(servlet)来访问。

Ear文件(扩展名为.Ear,Enterprise Application Archive)包含全部企业应用程序。在这种情形下,一个企业应用程序被定义为多个jar文件、资源、类和Web应用程序的集合。

每一种文件(.jar, .war, .ear)只能由应用服务器(application servers)、小型服务程序容器(servlet containers)、EJB容器(EJB containers)等进行处理。

有哪些保留选项?

  • -keep {Modifier} {class_specification} 保护指定的类文件和类的成员
  • -keepclassmembers {Modifier} {class_specification} 保护指定类的成员,如果此类受到保护他们会保护得更好
  • -keepclasseswithmembers {class_specification} 保护指定的类和类的成员,但条件是所有指定的类和类的成员是要存在的
  • -keepnams {class_specification} 保护指定的类的成员和名称(如果他们不会在压缩的过程中被删除)
  • -keepclassmembernames {class_specification} 保护指定类的成员的名称(如果他们不会在压缩的过程中被删除)
  • -keepclasseswithmembersnams {class_specification} 保护指定的类和类成员的名称,如果所有指定的类成员出席(在压缩之后)
  • -printseeds {filename} 列出类和类成员-keep选项的清单,标准输出到给定的文件

压缩

  • dontshrink 不压缩输入的类文件
  • printusage {filename}
  • whyareyoukeeping {class_specification}

优化

  • -dontoptimize 不优化输入的类文件
  • -assumenosideeffects {class_specification} 优化时假设指定的方法,没有任何副作用
  • -allowaccessmodification 优化时允许访问并修改有修饰符的类和类的成员

混淆

  • -dontobfuscate 不混淆输入的类文件
  • -printmapping {filename}
  • -applymapping {filename} 重用映射增加混淆
  • -obfuscationdictionary {filename} 使用给定文件中的关键字作为要混淆方法的名称
  • -overloadaggressively 混淆时应用侵入式重载
  • -useuniqueclassmembernames 确定统一的混淆类的成员名称来增加混淆
  • -flattenpackagehierarchy {package_name} 重新包装所有重命名的包并放在给定的单一包中
  • -repackageclass {package_name} 重新包装所有重命名的类文件中放在给定的单一包中
  • -dontusemixedcaseclassnames 混淆时不会产生形形色色的类名
  • -keepattributes {attribute_name,...} 保护给定的可选属性,例如LocalVariableTable(本地变量), SourceFile(源文件), InnerClasses(内部类)
  • -renamesourcefileattribute {string} 设置源文件中给定的字符串常量

上面介绍了一下ProGuard的基本方法

下面来介绍一下Android中的混淆文件。
对应于项目下的proguard-rules.pro文件

基本配置项

1.指定要处理的应用程序jar,war,ear和目录所需要的程序库文件

-libraryjars libs/apns_1.0.6.jar
-libraryjars libs/armeabi/libBaiduMapSDK_v2_3_1.so
-libraryjars libs/armeabi/liblocSDK4.so
-libraryjars libs/core.jar
-libraryjars libs/gesture-imageview.jar
-libraryjars libs/gson-2.6.2.jar
-libraryjars libs/infogracesound.jar
-libraryjars libs/universal-image-loader-1.9.0.jar

方法: libraryjars jar路径 ->libraryjars 项目中导入的jar包等
现在Studio的话可以忽略此配置了。

2.不优化输入的class文件,默认情况下是启用优化的

#不优化输入的class文件,默认情况下是启用优化的
-dontoptimize

3.Proguard对你的代码进行迭代优化的次数 0~7,一直优化到代码不能被优化为止

#Proguard对你的代码进行迭代优化的次数 0~7,一直优化到代码不能被优化为止
-optimizationpasses 5

4.跳过库中非public的类,可以加快proguard处理速度;但是有些类库包含从public类中继承来的非public类。这时如果加了这条会产生一个warning(find classes)

-skipnonpubliclibraryclasses

5.指定不去忽略非公共的库类

-dontskipnonpubliclibraryclasses

6.指定不去忽略包可见的库类的成员。

-dontskipnonpubliclibraryclassmembers

7.确定统一的混淆类的成员名称来增加混淆

-useuniqueclassmembernames

8.混淆时不会产生形形色色的类名

-dontusemixedcaseclassnames

9.混淆前认证,去掉可加快混淆速度

-dontpreverify

10.假如项目中有用到注解,保留注解,不混淆

-keepattributes *Annotation*

Android中的配置项

1.保留所有的v4包中类不被混淆

-keep class android.support.v4.**

2.保留所有的v4包中接口不被混淆

-keep interface android.support.v4.**

3.保留系统中继承v4/v7包的类,不被混淆

-keep class android.support.** { *; }
-keep class android.support.v4.** { *; }
-keep public class * extends android.support.v4.**
-keep interface android.support.v4.app.** { *; }
-keep class android.support.v7.** { *; }
-keep public class * extends android.support.v7.**
-keep interface android.support.v7.app.** { *; }
-dontwarn android.support.**

4.保留系统中继实现v4/v7包的接口,不被混淆

-keep public class * implements android.support.v4.**
-dontwarn android.support.v4.**

5.所有的native方法不被混淆

-keepclasseswithmembers class * {
    native <methods>;
}

6.自定义View构造方法不混淆

-keepclasseswithmembers class * {
    public <init>(android.content.Context);
}
-keepclasseswithmembers class * {
    public <init>(android.content.Context,android.util.AttributeSet);
}
-keepclasseswithmembers class * {
    public <init>(android.content.Context,android.util.AttributeSet,int);
}

被Android Resource 文件引用到,名字已经固定,不能混淆。

7.枚举不被混淆

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

8.release版不打印log

-assumenosideeffects class android.util.Log {
    public static *** d(...);
    public static *** v(...);
    public static *** i(...);
    public static *** e(...);
    public static *** w(...);
}

9.四大组件不能混淆

-dontwarn android.support.v4.**
-keep class android.support.v4.app.** { *; }
-keep interface android.support.v4.app.** { *; }
-keep class android.support.v4.** { *; }
-keep public class * extends android.app.Application

-dontwarn android.support.v7.**
-keep class android.support.v7.internal.** { *; }
-keep interface android.support.v7.internal.** { *; }
-keep class android.support.v7.** { *; }

-keep public class * extends android.app.Activity
-keep public class * extends android.app.Fragment
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keep public class * extends android.app.backup.BackupAgentHelper
-keep public class * extends android.preference.Preference

10.Design包不混淆

-dontwarn android.support.design.**
-keep class android.support.design.** { *; }
-keep interface android.support.design.** { *; }
-keep public class android.support.design.R$* { *; }

11.确保JavaBean不被混淆-否则Gson将无法将数据解析成具体对象

-keep class com.rair.circle.bean.** { *; }
-keep class com.rair.circle.db.bean.** { *; }

12.不混淆资源类

-keepclassmembers class **.R$* {
    public static <fields>;
}

13.忽略警告

-ignorewarning

当我们使用第三方框架,jar包,如果配置混淆,都有对应的混淆配置提供。
例如Jpush(极光推送)



我们只要copy到项目混淆文件中就行

最后

混淆时是否记录日志

-verbose  

1.apk包内所有 class 的内部结构

-dump class_files.txt  

2.未混淆的类和成员

-printseeds seeds.txt  

3.列出从 apk 中删除的代码

-printusage unused.txt  

4.混淆前后的映射

-printmapping mapping.txt  

把混淆配置好后,记得在build.gradle打开混淆(设置为true)

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

推荐阅读更多精彩内容