Android 代码混淆问题

 一般Android项目,如果不想被反编译查看源码的话,这就需要我们去做一些安全措施;最基础的便是代码混淆。然而代码混淆并不能使程序绝对的安全,但是用来防止一些非专业的人足够了。

 混淆处理的命令

     1) 保持不混淆 -keep class 或 -keep public class xx.xx.类名,如
            -keep public class * extends android.app.Activity

      2 )第三方jar包引用 -libraryjars libs/xx.jar,如
             -libraryjars libs/volley.jar

      3 )忽略作用域下的警告 -dontwarn xx.xx.xx.类名,如
            -dontwarn android.webkit.WebView

      4 )忽略所有警告
            -ignorewarnings

      5 )保持类不被混淆,并指明作用域,如
            -keep class com.umai.taok.manager.ClientAPI {
                public *;
            }

      6 )保持类对象域不被混淆,如
             -keepclassmembers class com.umai.taok.manager.ClientAPI {
                public *;
            }

     混淆步骤

      1) 对于android原生的类,不必做混淆处理 

            -keep public class * extends android.app.Fragment  
            -keep public class * extends android.app.Activity
            -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
            -keep public class * extends android.support.v4.**
            -keep public class com.android.vending.licensing.ILicensingService

      2) 对于第三方引用的jar包,需要声明

            -libraryjars libs/xUtils-2.6.14.jar
            -libraryjars libs/volley.jar
            -libraryjars libs/umeng-analytics-v5.5.3.jar
            -libraryjars libs/umeng_social_sdk.jar
            -libraryjars libs/sun.misc.BASE64Decoder.jar
            -libraryjars libs/SocialSDK_WeiXin_1.jar
            -libraryjars libs/SocialSDK_WeiXin_2.jar
            -libraryjars libs/SocialSDK_Sina.jar
            -libraryjars libs/SocialSDK_QQZone_1.jar
            -libraryjars libs/SocialSDK_QQZone_2.jar
            -libraryjars libs/SocialSDK_QQZone_3.jar
            -libraryjars libs/jpush-sdk-release1.8.1.jar
            -libraryjars libs/httpmime-4.1.1.jar
            -libraryjars libs/core-3.0.0.jar
            -libraryjars libs/Android_Location_V1.3.2.jar
            -libraryjars libs/Android_2DMapApi_V2.4.1.jar
            -libraryjars libs/AMap_3DMap_V2.4.1.jar

      3) 第三方的jar包源码,不必做混淆处理

              -keep public class com.umeng.socialize.* {*;}
             -keep class com.facebook.**
             -keep class com.amap.api.mapcore.**{*;} 
             -keep class com.amap.api.maps.**{*;} 
             -keep class com.autonavi.amap.mapcore.*{*;}  
             -keep class cn.jpush.** { *; }

      4)WebView相关的混淆处理 
       
            -keepclassmembers class com.umai.taok.manager.JSBridge$AndroidAPI {
                  public *;
            }
           -keepclassmembers class com.umai.taok.manager.ClientAPI {
                 public *;
            }
            -keep class com.umai.taok.manager.JSBridge$AndroidAPI {
                public *;
              }
           -keep class com.umai.taok.manager.ClientAPI {
                public *;
             } 

           -dontwarn bolts.**    

           -keepattributes *Annotation*  
          -keepattributes *JavascriptInterface*  


说明备注:

1、混淆配置的文件proguard-project.txt和project.properties。在 project.properties中系统已经添加了混淆文件的配置(#为注释符)。
# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir,       user.home):
#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
project.properties中红色标注部分的注释放开即可。在proguard-project.txt中,我们可以进行混淆的添加。

2、不同的框架都提供了不同的混淆添加部分,这部分引用我们可以从开发平台copy到代码中。需要我们去添加的有三部分: (1) 第三方jar包的引用声明  (2)WebVIew的相关配置(说明见_3)(3)根据错误信息进行遗漏配置的补全以及警告隐藏

3、WebView的混淆需要进行配置,特别是webview与Js进行交互时,在混淆后有可能会失去效果。首先,我们需要先对进行Js交互的类进行保持处理,(由于我用JSBridge进行交互,所以需要两个Js接口类,如下

-keepclassmembers 包名.类名 { // 该类为Js调用方法的承载类
   public *; // 公共方法
   *; // 所有方法
}
-keepclassmembers class  包名.类名 {
   public *;
}

如果Js调用方法的承载类为内部类,则需要如下添加

-keepclassmembers 包名.类名1$类名2 { // 类1 = 承载类的外部类,类2 = 承载类
   public *; // 公共方法
   *; // 所有方法
}
-keepclassmembers class  包名.类名1$类名2 {
   public *;
}

在进行上述保持不混淆处理后,还需要添加以下配置

-keepattributes *Annotation*  
-keepattributes *JavascriptInterface* 

4、如果代码中使用了Facebook的Fresco框架,为了保证不混淆,需要添加如下配置

 -keep class com.facebook.** { *; }
 -dontwarn com.facebook.**

5、添加之后打包会出现些许的Bug,详见console. 我们可以根据Bug反馈进行进一步处理
    
      1)如果出现找不到引用的情况,我们需要检查该引用是否被混淆,如果是,则需要添加保持
            -keep class com.aps.** { *; }  
      2) 如果出现不必要的警告的提示,我们需要对这些警告设置忽略提示 
           -dontwarn com.aps.**

下面是我自己项目中用到的混淆配置策略:
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in C:\Users\jasonxiao\AppData\Local\Android\sdk/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.
#
# For more details, see
#   http://developer.android.com/guide/developing/tools/proguard.html

# Add any project specific keep options here:

# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
#   public *;
#}
-keepattributes SourceFile,LineNumberTable


#不压缩输入的类文件
-dontshrink
#指定代码的压缩级别
-optimizationpasses 5
#包明不混合大小写
-dontusemixedcaseclassnames
#不去忽略非公共的库类
-dontskipnonpubliclibraryclasses
#优化  不优化输入的类文件
-dontoptimize
#预校验
-dontpreverify
#混淆时是否记录日志
 -verbose
# 混淆时所采用的算法
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
#保护注解
-keepattributes *Annotation*
#忽略警告
-ignorewarnings

-keep public class * extends android.app.Activity      # 保持哪些类不被混淆
-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        # 保持哪些类不被混淆
-keep public class com.android.vending.licensing.ILicensingService    # 保持哪些类不被混淆
-keep public class com.google.vending.licensing.ILicensingService   # 保持哪些类不被混淆


-keepclassmembers class **.R$* {
    public static ;
    public static final int *;
}
-keepclasseswithmembernames class * {  # 保持 native 方法不被混淆
    native ;
}
-keepclasseswithmembers class * {   # 保持自定义控件类不被混淆
    public (android.content.Context, android.util.AttributeSet);
}
-keepclasseswithmembers class * {# 保持自定义控件类不被混淆
    public (android.content.Context, android.util.AttributeSet, int);
}
-keepclassmembers class * extends android.app.Activity { # 保持自定义控件类不被混淆
    public void *(android.view.View);
}
-keepclassmembers enum * {     # 保持枚举 enum 类不被混淆
    public static **[] values();
    public static ** valueOf(java.lang.String);
}
-keep class * implements android.os.Parcelable { # 保持 Parcelable 不被混淆
    public static final android.os.Parcelable$Creator *;
}

-keep public class * extends android.view.View {
    public (android.content.Context);
    public (android.content.Context, android.util.AttributeSet);
     public (android.content.Context, android.util.AttributeSet, int);
    public void set*(...);
    }
-keepclassmembers public class * extends android.view.View {
   void set*(***);
   *** get*();
}

#apk 包内所有 class 的内部结构
#-dump class_files.txt
#未混淆的类和成员
#-printseeds seeds.txt
#列出从 apk 中删除的代码
#-printusage unused.txt
#混淆前后的映射
#-printmapping mapping.txt

#fastjson 可以混淆也可以不混淆
#-keep class javax.ws.rs.** { *; }
#-dontwarn com.alibaba.fastjson.**
#-keep class com.alibaba.fastjson.** { *; }
-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();
    public ;
}
-keepattributes Signature

#gson
-dontwarn com.google.gson.**
-keep class com.google.gson.** { *;}
-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();
    public ;
}

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

#greendao
#-dontwarn de.greenrobot.dao.**
#-keep class de.greenrobot.dao.** { *;}
-keepclassmembers class * extends de.greenrobot.dao.AbstractDao {
    public static java.lang.String TABLENAME;
}
-keep class **$Properties

#删除日志代码(标识无效代码)
-assumenosideeffects class android.util.Log {
public static boolean isLoggable(java.lang.String, int);
public static int v(...);
public static int i(...);
public static int w(...);
public static int d(...);
public static int e(...);
}


#ACRA specifics
# Restore some Source file names and restore approximate line numbers in the stack traces,
# otherwise the stack traces are pretty useless
-keepattributes SourceFile,LineNumberTable

# ACRA needs "annotations" so add this...
# Note: This may already be defined in the default "proguard-android-optimize.txt"
# file in the SDK. If it is, then you don't need to duplicate it. See your
# "project.properties" file to get the path to the default "proguard-android-optimize.txt".
-keepattributes *Annotation*


-dontwarn javax.annotation.**
-dontwarn javax.inject.**
-dontwarn sun.misc.Unsafe


# Keep all the ACRA classes
-keep class org.acra.** { *; }


#okhttp
# Don't warn about removed methods from AppCompat
-dontwarn android.support.v4.app.NotificationCompat*

#所有业务中的数据类不混淆(混淆后Gson无法解析)
-keep class com.zhijiankeji.dlyw.index.** { *; }
-keep class com.zhijiankeji.dlyw.common.** { *; }
-keep class com.zhijiankeji.dlyw.ezviz.** { *; }
-keep class com.zhijiankeji.dlyw.home.** { *; }
-keep class com.zhijiankeji.dlyw.me.vo.** { *; }
-keep class com.zhijiankeji.dlyw.index.** { *; }
-keep class com.zhijiankeji.dlyw.vo.** { *; }

-keep public class com.zhijiankeji.dlyw.common.BaseResponse { *; }
-keep public class com.zhijiankeji.dlyw.common.BaseResponse.ErrorResponseEntity{ *; }

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


#alibaba
-keepattributes InnerClasses
-keep class com.alibaba.android.vlayout.ExposeLinearLayoutManagerEx { *; }
-keep class android.support.v7.widget.RecyclerView$LayoutParams { *; }
-keep class android.support.v7.widget.RecyclerView$ViewHolder { *; }
-keep class android.support.v7.widget.ChildHelper { *; }
-keep class android.support.v7.widget.RecyclerView$LayoutManager { *; }


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


#android-Ultra-Pull-To-Refresh
-keep class in.srain.** { *; }
#-dontwarn class in.srain.cube.image.ImageProvider
#-dontwarn class android.graphics.Bitmap
#-ignorewarnings class in.srain.cube.image.ImageProvider
#-ignorewarnings class android.graphics.Bitmap

##---------------End: proguard configuration for Gson  ----------

#guava
-dontwarn com.google.common.base.**
-keep class com.google.common.base.** {*;}
-dontwarn com.google.errorprone.annotations.**
-keep class com.google.errorprone.annotations.** {*;}
-dontwarn   com.google.j2objc.annotations.**
-keep class com.google.j2objc.annotations.** { *; }
-dontwarn   java.lang.ClassValue
-keep class java.lang.ClassValue { *; }
-dontwarn   org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement
-keep class org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement { *; }

-dontwarn okio.**
-dontwarn okhttp3.**
-dontwarn org.apache.mina.**
-keep class org.apache.mina.**{*;}
-dontwarn org.slf4j.**
-dontwarn com.tencent.**
-dontwarn com.alibaba.sdk.android.**
-dontwarn com.baidu.location.**
-keep class com.baidu.location.** {*;}
-keep class com.baidu.lbsapi.** {*;}
-keep class com.baidu.platform.** {*;}


##---------------Begin: proguard configuration for Retrofit  ----------
# Platform calls Class.forName on types which do not exist on Android to determine platform.
-dontnote retrofit2.Platform
# Platform used when running on RoboVM on iOS. Will not be used at runtime.
-dontnote retrofit2.Platform$IOS$MainThreadExecutor
# Platform used when running on Java 8 VMs. Will not be used at runtime.
-dontwarn retrofit2.Platform$Java8
# Retain generic type information for use by reflection by converters and adapters.
-keepattributes Signature
# Retain declared checked exceptions for use by a Proxy instance.
-keepattributes Exceptions
##---------------End: proguard configuration for Retrofit  --------


#支付宝代码混淆
-dontwarn android.net.**
-keep class android.net.SSLCertificateSocketFactory{*;}
-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 *;}


#EventBus混淆
-keepclassmembers class ** {
    @org.greenrobot.eventbus.Subscribe ;
}
-keep enum org.greenrobot.eventbus.ThreadMode { *; }

# Only required if you use AsyncExecutor
-keepclassmembers class * extends org.greenrobot.eventbus.util.ThrowableFailureEvent {
    (java.lang.Throwable);
}


#view子类代码不混淆
-keep class com.yuerbao.common.widget.**{*;}



###---------------Begin: proguard configuration for Gson  ----------
## Gson uses generic type information stored in a class file when working with fields. Proguard
## removes such information by default, so configure it to keep all of it.
#-keepattributes Signature
#
## For using GSON @Expose annotation
#-keepattributes *Annotation*
#
## Gson specific classes
#-keep class sun.misc.Unsafe { *; }
##-keep class com.google.gson.stream.** { *; }
#
## Application classes that will be serialized/deserialized over Gson
#-keep class com.google.gson.examples.android.model.** { *; }
#
## Prevent proguard from stripping interface information from TypeAdapterFactory,
## JsonSerializer, JsonDeserializer instances (so they can be used in @JsonAdapter)
#-keep class * implements com.google.gson.TypeAdapterFactory
#-keep class * implements com.google.gson.JsonSerializer
#-keep class * implements com.google.gson.JsonDeserializer
#
###---------------End: proguard configuration for Gson  ----------

##---------------Begin: proguard configuration for Gson  ----------
# Gson uses generic type information stored in a class file when working with fields. Proguard
# removes such information by default, so configure it to keep all of it.
-keepattributes Signature

# For using GSON @Expose annotation
-keepattributes *Annotation*

# Gson specific classes
-keep class sun.misc.Unsafe { *; }
#-keep class com.google.gson.stream.** { *; }

# Application classes that will be serialized/deserialized over Gson
#-keep class com.google.gson.examples.android.model.** { *; }

# Prevent proguard from stripping interface information from TypeAdapterFactory,
# JsonSerializer, JsonDeserializer instances (so they can be used in @JsonAdapter)
-keep class * implements com.google.gson.TypeAdapterFactory
-keep class * implements com.google.gson.JsonSerializer
-keep class * implements com.google.gson.JsonDeserializer

-dontwarn com.ezviz.player.**
-keep class com.ezviz.player.** { *;}

-dontwarn com.ezviz.statistics.**
-keep class com.ezviz.statistics.** { *;}

-dontwarn com.ezviz.stream.**
-keep class com.ezviz.stream.** { *;}

-dontwarn com.hik.**
-keep class com.hik.** { *;}

-dontwarn com.hikvision.**
-keep class com.hikvision.** { *;}

-dontwarn com.videogo.**
-keep class com.videogo.** { *;}

-dontwarn com.videogo.**
-keep class org.MediaPlayer.PlayM4.** { *;}
 
    

上述内容皆非原创,来自网络资料

你可能感兴趣的:(Android)