Android代码混淆配置(Proguard文件解析)

为了防止自己的APP被轻易反编译,我们需要对APK进行混淆,或者特殊加密处理。可以用“爱加密“提供的加密服务,反编译后只能看到几行代码和.so的库文件。本文说说android 如何配置混淆。
关于如何反编译android apk,见我另外一篇文章:win/mac下反编译Android安装包-APK文件,http://blog.csdn.net/dzsw0117/article/details/51429683

一,何为混淆?

简单的说,就是将原本正常的项目文件,对其类,方法,字段,重新命名,a,b,c,d,e,f…之类的字母,达到混淆代码的目的,这样反编译出来,结构乱糟糟的,看了也头大。

二,官方默认的混淆配置

先看看官方的proguard-android.txt文件,位于/tools/proguard目录下,不知道怎么写,可以当成模板,复制一份出来到自己的工程,改成自己项目所需的混淆配置。内容如下:

# This is a configuration file for ProGuard.
# http://proguard.sourceforge.net/index.html#manual/usage.html

-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-verbose

# Optimization is turned off by default. Dex does not like code run
# through the ProGuard optimize and preverify steps (and performs some
# of these optimizations on its own).
-dontoptimize
-dontpreverify
# Note that if you want to enable optimization, you cannot just
# include optimization flags in your own project configuration file;
# instead you will need to point to the
# "proguard-android-optimize.txt" file instead of this one from your
# project.properties file.

-keepattributes *Annotation*
-keep public class com.google.vending.licensing.ILicensingService
-keep public class com.android.vending.licensing.ILicensingService

# For native methods, see http://proguard.sourceforge.net/manual/examples.html#native
-keepclasseswithmembernames class * {
    native ;
}

# keep setters in Views so that animations can still work.
# see http://proguard.sourceforge.net/manual/examples.html#beans
-keepclassmembers public class * extends android.view.View {
   void set*(***);
   *** get*();
}

# We want to keep methods in Activity that could be used in the XML attribute onClick
-keepclassmembers class * extends android.app.Activity {
   public void *(android.view.View);
}

# For enumeration classes, see http://proguard.sourceforge.net/manual/examples.html#enumerations
-keepclassmembers enum * {
    public static **[] values();
    public static ** valueOf(java.lang.String);
}

-keepclassmembers class * implements android.os.Parcelable {
  public static final android.os.Parcelable$Creator CREATOR;
}

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

# The support library contains references to newer platform versions.
# Don't warn about those in case this app is linking against an older
# platform version.  We know about them, and they are safe.
-dontwarn android.support.**

# Understand the @Keep support annotation.
-keep class android.support.annotation.Keep

-keep @android.support.annotation.Keep class * {*;}

-keepclasseswithmembers class * {
    @android.support.annotation.Keep ;
}

-keepclasseswithmembers class * {
    @android.support.annotation.Keep ;
}

-keepclasseswithmembers class * {
    @android.support.annotation.Keep (...);
}

以上英文好好琢磨下,这个混淆默认采取一些通用的规则,view,activity,Parcelable,注解,R文件,枚举这类的东西都不会混淆,我们也不能混淆这些,否则release版本会报错。

三,Android Studio开启混淆配置

很简单,只要设置minifyEnabled为true即可。

 buildTypes {
        release {
            minifyEnabled true//true开启混淆配置,false关闭
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            signingConfig signingConfigs.duqian_android_keystore
        }
       debug{//省略}
    }

四,Android混淆的通用规则

debug调试的apk是没有混淆的,所以无论你怎么反编译,都看到的是源码,你要检验release包是否混淆。

1,系统混淆配置

-dontusemixedcaseclassnames          #混淆时不使用大小写混合类名
-dontskipnonpubliclibraryclasses     #不跳过library中的非public的类
-verbose                             #打印混淆的详细信息
-dontoptimize                        #不进行优化,建议使用此选项,
-dontpreverify                       #不进行预校验,Android不需要,可加快混淆速度。
-ignorewarnings                      #忽略警告
#-optimizationpasses 5               #指定代码的压缩级别

2,常用的一些混淆配置

-keepattributes Signature #范型
#native方法不混淆
-keepclasseswithmembernames class * {
    native ;
}
#v4包不混淆
-keep class android.support.v4.app.** { *; }
-keep interface android.support.v4.app.** { *; }
#Gson混淆配置
-keep class sun.misc.Unsafe { *; }
-keep class com.idea.fifaalarmclock.entity.***
-keep class com.google.gson.** { *; }
#JavaBean
-keepclassmembers public class cn.net.duqian.bean.** {
   void set*(***);
   *** get*();
}
-keep class com.xx.duqian_cloud.JavaScriptInterface { *; }#webview js

#忽略 libiary 混淆
-keep class io.vov.vitamio.** { *; }

#butterknife不混淆
-keep class butterknife.** { *; }
-dontwarn butterknife.internal.**
-keep class **$$ViewBinder { *; }
-keepclasseswithmembernames class * {
    @butterknife.* ;
}
-keepclasseswithmembernames class * {
    @butterknife.* ;
}

第三方框架不混淆,也要看具体情况,不是所有的lib都不能混淆。用了反射的肯定不能混淆。

-keepclassmembers class * {
   public  (org.json.JSONObject);
}
#okhttp
-dontwarn okhttp3.**
-keep class okhttp3.**{*;}
-keep interface okhttp3.**{*;}

#okio
-dontwarn okio.**
-keep class okio.**{*;}
-keep interface okio.**{*;}

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

-dontwarn rx.**
-keep class rx.**{*;}

五,Android混淆的方法和通配符对照表

引用的图片,未必准确:
Android代码混淆配置(Proguard文件解析)_第1张图片
Android代码混淆配置(Proguard文件解析)_第2张图片

六,Android混淆的总结

  1. Java的反射,为什么不能混淆呢?因为代码混淆,类名、方法名、属性名都改变了,而反射它还是按照原来的名字去反射,结果只射出一个程序崩溃,Crash,一脸的懵逼。
  2. 注解用了反射,所以不能混淆。 不混淆任何包含native方法的类的类名以及native方法名,否则找不到本地方法。
  3. Activity更不能混淆,因为AndroidManifest.xml文件中是完整的名字,混淆后怎么找?
  4. 自定义view也是带了包名写在xml布局中,给我换成a,怎么破? R文件混淆了,id没了,界面崩溃那时自然咯。
  5. 本文没有指定混淆某个类中的某个方法。
  6. 如何反编译apk,见我另外一篇文章:win/mac下反编译Android安装包-APK文件
欢迎交流,Dusan,杜乾,291902259。

你可能感兴趣的:(Android,Base)