安卓混淆

一.名称解释和介绍

代码混淆(Obfuscated code)亦称花指令,是将计算机程序的代码,转换成一种功能上等价,但是难于阅读和理解的形式的行为。

Android SDK 自带了混淆工具Proguard。它位于SDK根目录\tools\proguard下面。如果开启了混淆,Proguard默认情况下会对所有代码,包括第三方包都进行混淆,可是有些代码或者第三方包是不能混淆的,这就需要我们手动编写混淆规则来保持不能被混淆的部分。
混淆有几个作用:

  • 【优化】它能优化java的字节码,使程序运行更快;
  • 【压缩】最直观的就是减少App大小,在混淆过程中它会找出未被使用过的类和类成员并删除他们;
  • 【混淆】这个功能使我们的java代码中的类、函数、变量名随机变成无意义的代号形如:a,b,c...之类的,即使我们的APP即使被反编译,也不容易理解了。

 

二.修改配置文件

2.1文件解释

proguard-project.txt:代码混淆相关文件不能被混淆的代码规则

proguard-rules.pro:混淆打包的配置文件(针对我们自己的项目需要特别定义混淆规则

2.2文件设置

在build.gradle文件中设置
buildTypes {
    release {
        zipAlignEnabled true //优化我们的java字节码,提高运行效率
        shrinkResources true //资源的压缩
        useProguard true //代码压缩
        minifyEnabled true //开启混淆
        // 前一部分代表系统默认的android程序的混淆文件,该文件已经包含了基本的混淆声明,后一个文件是自己的定义混淆文件
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    }
}

2.3proguard-rules.pro文件的作用

  • 只要在工程应用目录的gradle文件中设置minifyEnabled:true即可。然后我们就可以到proguard-rules.pro文件中加入我们的混淆规则了
  • Proguard是一个集文件压缩,优化,混淆和校验等功能的工具
  • 它检测并删除无用的类,变量,方法和属性
  • 它优化字节码并删除无用的指令.
  • 它通过将类名,变量名和方法名重命名为无意义的名称实现混淆效果.
  • 最后它还校验处理后的代码

 

2.3.1Proguard关键字

Proguard关键字

描述

dontwarn

dontwarn是一个和keep可以说是形影不离,尤其是处理引入的library时.

keep

保留类和类中的成员,防止被混淆或移除

keepnames

保留类和类中的成员,防止被混淆,成员没有被引用会被移除

keepclassmembers

只保留类中的成员,防止被混淆或移除

keepclassmembernames

只保留类中的成员,防止被混淆,成员没有引用会被移除

keepclasseswithmembers

保留类和类中的成员,防止被混淆或移除,保留指明的成员

keepclasseswithmembernames

保留类和类中的成员,防止被混淆,保留指明的成员,成员没有引用会被移除

 

 

2.3.2Keep选项概述对比(Overview of Keep Options)

作用范围

保持所指定类、成员

所指定类、成员在压缩阶段没有被删除,才能被保持

类和类成员

-keep

-keepnames

仅类成员

-keepclassmembers

-keepclassmembernames

类和类成员

-keepclasseswithmembers

-keepclasseswithmembernames

  • 建议初学者,如果不确定用哪个keep选项就尽量用-keep,这个比较简单且不易使混淆代码出错。
  • 如果只指定类被保留,那么它的成员同样可能会被压缩、优化或者混淆。
  • 如果指定类成员被保留,那么其他代码也有可能会被压缩、优化或者混淆

 

2.3.3Proguard通配符

Proguard通配符

描述

<field>

匹配类中的所有字段

<method>

匹配类中所有的方法

<init>

匹配类中所有的构造函数

*

匹配任意长度字符,不包含包名分隔符(.)

**

匹配任意长度字符,包含包名分隔符(.)

***

匹配任意参数类型

三.不能混淆的文件

1.使用了自定义控件那么要保证它们不参与混淆

2.使用了枚举要保证枚举不被混淆

3.运用了反射的类也不进行混淆

4. 使用了 Gson 之类的工具要使 JavaBean 类即实体类不被混淆

5. 在引用第三方库的时候,一般会标明库的混淆规则的,建议在使用的时候就把混淆规则添加上去,免得到最后才去找

6.有用到 WebView 的 JS 调用也需要保证写的接口方法不混淆,原因和第一条一样

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

8.使用的四大组件,自定义的Application* 实体类

9. JNI中调用的类,对于NDK开发 本地的native方法不能被混淆

-keepclasseswithmembernames class * { native <methods>; }

10.Layout布局使用的View构造函数(自定义控件)、android:onClick等。

11.Annotation注释不能混淆

-keepattributes *Annotation*

四.通用混淆模板

proguard-android.txt文件是系统默认的混淆文件,具体在../sdk/tools/proguard/目录下,其中包含了android最基本的混淆,一般不需要改动,我们需要配置的是项目中app下的proguard-rules.pro文件,在此提供一份混淆模板。

找到对应moudle的proguard-rules.pro文件进行配置如下面:

基本混淆

#############################################
#
# 对于一些基本指令的添加
#
#############################################
# 代码混淆压缩比,在0~7之间,默认为5,一般不做修改
-optimizationpasses 5
 
# 混合时不使用大小写混合,混合后的类名为小写
-dontusemixedcaseclassnames
 
# 指定不去忽略非公共库的类
-dontskipnonpubliclibraryclasses
 
# 这句话能够使我们的项目混淆后产生映射文件
# 包含有类名->混淆后类名的映射关系
-verbose
 
# 指定不去忽略非公共库的类成员
-dontskipnonpubliclibraryclassmembers
 
# 不做预校验,preverify是proguard的四个步骤之一,Android不需要preverify,去掉这一步能够加快混淆速度。
-dontpreverify
 
# 保留Annotation不混淆
-keepattributes *Annotation*,InnerClasses
 
# 避免混淆泛型
-keepattributes Signature
 
# 抛出异常时保留代码行号
-keepattributes SourceFile,LineNumberTable
 
# 指定混淆是采用的算法,后面的参数是一个过滤器
# 这个过滤器是谷歌推荐的算法,一般不做更改
-optimizations !code/simplification/cast,!field/*,!class/merging/*
 
 
#############################################
#
# Android开发中一些需要保留的公共部分
#
#############################################
 
# 保留我们使用的四大组件,自定义的Application等等这些类不被混淆
# 因为这些子类都有可能被外部调用
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Appliction
-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
-keep public class * extends android.view.View
-keep public class com.android.vending.licensing.ILicensingService
 
 
# 保留support下的所有类及其内部类
-keep class android.support.** {*;}
 
# 保留继承的
-keep public class * extends android.support.v4.**
-keep public class * extends android.support.v7.**
-keep public class * extends android.support.annotation.**
 
# 保留R下面的资源
-keep class **.R$* {*;}
 
# 保留本地native方法不被混淆
-keepclasseswithmembernames class * {
    native <methods>;
}
 
# 保留在Activity中的方法参数是view的方法,
# 这样以来我们在layout中写的onClick就不会被影响
-keepclassmembers class * extends android.app.Activity{
    public void *(android.view.View);
}
 
# 保留枚举类不被混淆
-keepclassmembers enum * {
    public static **[] values();
    public static ** valueOf(java.lang.String);
}
 
# 保留我们自定义控件(继承自View)不被混淆
-keep public class * extends android.view.View{
    *** get*();
    void set*(***);
    public <init>(android.content.Context);
    public <init>(android.content.Context, android.util.AttributeSet);
    public <init>(android.content.Context, android.util.AttributeSet, int);
}
 
# 保留Parcelable序列化类不被混淆
-keep class * implements android.os.Parcelable {
    public static final android.os.Parcelable$Creator *;
}
 
# 保留Serializable序列化的类不被混淆
-keepclassmembers class * implements java.io.Serializable {
    static final long serialVersionUID;
    private static final java.io.ObjectStreamField[] serialPersistentFields;
    !static !transient <fields>;
    !private <fields>;
    !private <methods>;
    private void writeObject(java.io.ObjectOutputStream);
    private void readObject(java.io.ObjectInputStream);
    java.lang.Object writeReplace();
    java.lang.Object readResolve();
}
 
# 对于带有回调函数的onXXEvent、**On*Listener的,不能被混淆
-keepclassmembers class * {
    void *(**On*Event);
    void *(**On*Listener);
}
 
# webView处理,项目中没有使用到webView忽略即可
-keepclassmembers class fqcn.of.javascript.interface.for.webview {
    public *;
}
-keepclassmembers class * extends android.webkit.webViewClient {
    public void *(android.webkit.WebView, java.lang.String, android.graphics.Bitmap);
    public boolean *(android.webkit.WebView, java.lang.String);
}
-keepclassmembers class * extends android.webkit.webViewClient {
    public void *(android.webkit.webView, jav.lang.String);
}
 
# 移除Log类打印各个等级日志的代码,打正式包的时候可以做为禁log使用,这里可以作为禁止log打印的功能使用
# 记得proguard-android.txt中一定不要加-dontoptimize才起作用
# 另外的一种实现方案是通过BuildConfig.DEBUG的变量来控制
#-assumenosideeffects class android.util.Log {
#    public static int v(...);
#    public static int i(...);
#    public static int w(...);
#    public static int d(...);
#    public static int e(...);
#}
 
#############################################
#
# 项目中特殊处理部分
#
#############################################
 
#-----------处理反射类---------------
 
 
 
#-----------处理js交互---------------
 
 
 
#-----------处理实体类---------------
# 在开发的时候我们可以将所有的实体类放在一个包内,这样我们写一次混淆就行了。
#-keep public class com.ljd.example.entity.** {
#    public void set*(***);
#    public *** get*();
#    public *** is*();
#}

第三方依赖库混淆

#-----------处理第三方依赖库---------

# AndroidEventBus
-keep class org.simple.** { *; }
-keep interface org.simple.** { *; }
-keepclassmembers class * {
    @org.simple.eventbus.Subscriber <methods>;
}


# 百度地图(jar包换成自己的版本,记得签名要匹配)
-libraryjars libs/baidumapapi_v2_1_3.jar
-keep class com.baidu.** {*;}
-keep class vi.com.** {*;}
-keep class com.sinovoice.** {*;}
-keep class pvi.com.** {*;}
-dontwarn com.baidu.**
-dontwarn vi.com.**
-dontwarn pvi.com.**


# Bugly
-dontwarn com.tencent.bugly.**
-keep class com.tencent.bugly.** {*;}


# ButterKnife
-keep class butterknife.** { *; }
-dontwarn butterknife.internal.**
-keep class **$$ViewBinder { *; } 
-keepclasseswithmembernames class * {
    @butterknife.* <fields>;
}
-keepclasseswithmembernames class * {
    @butterknife.* <methods>;
}


# EventBus
-keepattributes *Annotation*
-keepclassmembers class ** {
    @org.greenrobot.eventbus.Subscribe <methods>;
}
-keep enum org.greenrobot.eventbus.ThreadMode { *; }


# Facebook
-keep class com.facebook.** {*;}
-keep interface com.facebook.** {*;}
-keep enum com.facebook.** {*;}


# FastJson
-dontwarn com.alibaba.fastjson.**
-keep class com.alibaba.fastjson.** { *; }
-keepattributes Signature
-keepattributes *Annotation*


# Fresco
-keep class com.facebook.fresco.** {*;}
-keep interface com.facebook.fresco.** {*;}
-keep enum com.facebook.fresco.** {*;}


# 高德相关依赖
# 集合包:3D地图3.3.2 导航1.8.0 定位2.5.0
-dontwarn com.amap.api.**
-dontwarn com.autonavi.**
-keep class com.amap.api.**{*;}
-keep class com.autonavi.**{*;}
# 地图服务
-dontwarn com.amap.api.services.**
-keep class com.map.api.services.** {*;}
# 3D地图
-dontwarn com.amap.api.mapcore.**
-dontwarn com.amap.api.maps.**
-dontwarn com.autonavi.amap.mapcore.**
-keep class com.amap.api.mapcore.**{*;}
-keep class com.amap.api.maps.**{*;}
-keep class com.autonavi.amap.mapcore.**{*;}
# 定位
-dontwarn com.amap.api.location.**
-dontwarn com.aps.**
-keep class com.amap.api.location.**{*;}
-keep class com.aps.**{*;}
# 导航
-dontwarn com.amap.api.navi.**
-dontwarn com.autonavi.**
-keep class com.amap.api.navi.** {*;}
-keep class com.autonavi.** {*;}


# Glide
-keep public class * implements com.bumptech.glide.module.GlideModule
-keep public enum com.bumptech.glide.load.resource.bitmap.ImageHeaderParser$** {
  **[] $VALUES;
  public *;
}


# Gson
-keepattributes Signature-keepattributes *Annotation*
-keep class sun.misc.Unsafe { *; }
-keep class com.google.gson.stream.** { *; }
# 使用Gson时需要配置Gson的解析对象及变量都不混淆。不然Gson会找不到变量。
# 将下面替换成自己的实体类
-keep class com.example.bean.** { *; }


# Jackson
-dontwarn org.codehaus.jackson.**
-dontwarn com.fasterxml.jackson.databind.**
-keep class org.codehaus.jackson.** { *;}
-keep class com.fasterxml.jackson.** { *; }


# 极光推送
-dontoptimize
-dontpreverify
-dontwarn cn.jpush.**
-keep class cn.jpush.** { *; }


# OkHttp
-keep class com.squareup.okhttp.** { *; }
-keep interface com.squareup.okhttp.** { *; }
-dontwarn com.squareup.okhttp.**


# OkHttp3
-dontwarn com.squareup.okhttp3.**
-keep class com.squareup.okhttp3.** { *;}
-dontwarn okio.**


# Okio
-dontwarn com.squareup.**  
-dontwarn okio.**  
-keep public class org.codehaus.* { *; }  
-keep public class java.nio.* { *; }


# OrmLite
-keepattributes *DatabaseField* 
-keepattributes *DatabaseTable* 
-keepattributes *SerializedName*  
-keep class com.j256.**
-keepclassmembers class com.j256.** { *; }
-keep enum com.j256.**
-keepclassmembers enum com.j256.** { *; }
-keep interface com.j256.**
-keepclassmembers interface com.j256.** { *; }


# Realm
-keep class io.realm.annotations.RealmModule
-keep @io.realm.annotations.RealmModule class *
-keep class io.realm.internal.Keep
-keep @io.realm.internal.Keep class * { *; }
-dontwarn javax.**
-dontwarn io.realm.**


# Retrofit
-dontwarn retrofit2.**
-keep class retrofit2.** { *; }
-keepattributes Signature
-keepattributes Exceptions


# Retrolambda
-dontwarn java.lang.invoke.*


# RxJava RxAndroid
-dontwarn sun.misc.**
-keepclassmembers class rx.internal.util.unsafe.*ArrayQueue*Field* {
    long producerIndex;
    long consumerIndex;
}
-keepclassmembers class rx.internal.util.unsafe.BaseLinkedQueueProducerNodeRef {
    rx.internal.util.atomic.LinkedQueueNode producerNode;
}
-keepclassmembers class rx.internal.util.unsafe.BaseLinkedQueueConsumerNodeRef {
    rx.internal.util.atomic.LinkedQueueNode consumerNode;
}


# Universal-Image-Loader-v1.9.5
-libraryjars libs/universal-image-loader-1.9.5-SNAPSHOT-with-sources.jar
-dontwarn com.nostra13.universalimageloader.**
-keep class com.nostra13.universalimageloader.** { *; }


# 微信支付
-dontwarn com.tencent.mm.**
-dontwarn com.tencent.wxop.stat.**
-keep class com.tencent.mm.** {*;}
-keep class com.tencent.wxop.stat.**{*;}


# 信鸽
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep class com.tencent.android.tpush.**  {* ;}
-keep class com.tencent.mid.**  {* ;}
-keepattributes *Annotation*


# 新浪微博
-keep class com.sina.weibo.sdk.* { *; }  
-keep class android.support.v4.* { *; }  
-keep class com.tencent.* { *; }  
-keep class com.baidu.* { *; }  
-keep class lombok.ast.ecj.* { *; }  
-dontwarn android.support.v4.**  
-dontwarn com.tencent.**s  
-dontwarn com.baidu.**  


# 讯飞语音
-dontwarn com.iflytek.**
-keep class com.iflytek.** {*;}


# xUtils3.0
-keepattributes Signature,Annotation
-keep public class org.xutils.** {
public protected *;
}
-keep public interface org.xutils.** {
public protected *;
}
-keepclassmembers class * extends org.xutils.** {
public protected *;
}
-keepclassmembers @org.xutils.db.annotation.* class * {;}
-keepclassmembers @org.xutils.http.annotation. class * {*;}
-keepclassmembers class * {
@org.xutils.view.annotation.Event ;
}


# 银联
-dontwarn com.unionpay.**
-keep class com.unionpay.** { *; }


# 友盟统计分析
-keepclassmembers class * { public <init>(org.json.JSONObject); }
-keepclassmembers enum com.umeng.analytics.** {
    public static **[] values();
    public static ** valueOf(java.lang.String);
}


# 友盟自动更新
-keepclassmembers class * { public <init>(org.json.JSONObject); }
-keep public class cn.irains.parking.cloud.pub.R$*{ public static final int *; }
-keep public class * extends com.umeng.**
-keep class com.umeng.** { *; }


# 支付宝钱包
-dontwarn com.alipay.**
-dontwarn HttpUtils.HttpFetcher
-dontwarn com.ta.utdid2.**
-dontwarn com.ut.device.**
-keep class com.alipay.android.app.IAlixPay{*;}
-keep class com.alipay.android.app.IAlixPay$Stub{*;}
-keep class com.alipay.android.app.IRemoteServiceCallback{*;}
-keep class com.alipay.android.app.IRemoteServiceCallback$Stub{*;}
-keep class com.alipay.sdk.app.PayTask{ public *;}
-keep class com.alipay.sdk.app.AuthTask{ public *;}
-keep class com.alipay.mobilesecuritysdk.*
-keep class com.ut.*

参考资料

https://mp.weixin.qq.com/s/Rr0atgupgoeHOEV3-20WqQ

https://blankj.com/2016/06/28/android-proguard-templet/

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值