Android混淆笔记

如何添加混淆呢?
这里我们使用as作为开发工具。一般我们会在gradle里进行如下设置:

    buildTypes {
        release {
            minifyEnabled false //是否压缩(没有用的方法以及资源 会进行压缩)
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'//
        }
    }

使用默认的proguard-android.txt文件的混淆,大致可总结如下三条:
1. Android四大基本组件(在AndroidManifest.xml中注册的)的类名和重写的父类方法名不会被混淆。
2. 含有本地native方法的类名以及其中的本地方法名不会被混淆。
3. 第三方Jar包都会被混淆(包括类名和方法名)。
proguard-android.txt,这个东西很吊的样子,啥都不用该混淆的不该混淆的全搞定。下面我们就具体学习一下里面的混淆规则:

# This is a configuration file for ProGuard.
# http://proguard.sourceforge.net/index.html#manual/usage.html
#表示混淆时不使用大小写混合类名。
-dontusemixedcaseclassnames
#表示不跳过library中非public的类。
-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).
#表示不进行优化,建议使用此选项,因为根据proguard-android-optimize.txt中的描述,优化可能会造成一些潜在风险,不能保证在所有版本的Dalvik上都运行正常。
-dontoptimize
#表示不进行预校验。这个预校验是作用在Java平台上的,Android平台上不需要此项功能,去掉之后还可以加快混淆速度。
-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*

#表示不混淆上述声明的两个类,这两个类我们基本也用不上,是接入Google原生的一些服务时使用的。
-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
#表示不混淆任何包含native方法的类名以及native方法名。
-keepclasseswithmembernames class * {
    native <methods>;
}

# keep setters in Views so that animations can still work.
# see http://proguard.sourceforge.net/manual/examples.html#beans
#表示不混淆任何一个View中的setXxx()和getXxx()方法,因为属性动画需要有相应的setter和getter的方法实现,混淆了就无法工作了。
-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
#表示不混淆Activity中参数是View的方法,因为有这样一种用法,在XML中配置android:onClick = "buttionClick"属性,当用户点击该按钮时就会调用Activity中buttonClick方法,如果被混淆就找不到了。
-keepclassmembers class * extends android.app.Activity {
   public void *(android.view.View);
}

# For enumeration classes, see http://proguard.sourceforge.net/manual/examples.html#enumerations
# 表示不混淆枚举类的values()和 valueOf()方法。
-keepclassmembers enum * {
    public static **[] values();
    public static ** valueOf(java.lang.String);
}
#表示不混淆Parcelable实现类中的CREATOR字段,毫无疑问,CREATOR字段是绝对不能改变的,包括大小写都不能变,不然整个Parecable工作机制都会失败。
-keepclassmembers class * implements android.os.Parcelable {
  public static final android.os.Parcelable$Creator CREATOR;
}

#表示不混淆R文件中所有的静态字段,R文件是通过字段来记录每个资源的id的,字段若被混淆,id就找不到了。
-keepclassmembers class **.R$* {
    public static <fields>;
}

# 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.
#表示对android:support包下的代码不警告,因为support包中有很多代码都是在高版本中使用的,如果我们的项目指定的版本较低在打包是就会给予警告。不过support包中所有的代码都在版本兼容性上做足了判断,因此不用担心代码会出问题,直接忽略警告就可以了。
-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 <methods>;
}

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

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

#另外 对于引用第三方包的情况,可以采用下面方式避免打包出错:
#-libraryjars libs/aaa.jar
#-dontwarn com.xx.yy.**
#-keep class com.xx.yy.** { *;}

下面我们来看一看六个keep相关的关键字:

关键字 描述
keep 保留类和类中的成员,防止它们被混淆或移除。
keepnames 保留类和类中的成员,防止它们被混淆,但当成员没有被引用时会被移除。
keepclassmembers 只保留类中的成员,防止它们被混淆或移除。
keepclassmembernames 只保留类中的成员,防止它们被混淆,但当成员没有被引用时会被移除。
keepclasseswithmembers 保留类和类中的成员,防止它们被混淆或移除,前提是指名的类中的成员必须存在,如果不存在则还是会混淆。
keepclasseswithmembernames 保留类和类中的成员,防止它们被混淆,但当成员没有被引用时会被移除,前提是指名的类中的成员必须存在,如果不存在则还是会混淆。

还有通配符:

通配符 描述
field 匹配类中的所有字段
method 匹配类中的所有方法
init 匹配类中的所有构造函数
* 匹配任意长度字符,但不含包名分隔符(.)。比如说我们的完整类名是com.example.test.MyActivity,使用com.,或者com.exmaple.都是无法匹配的,因为无法匹配包名中的分隔符,正确的匹配方式是com.exmaple..,或者com.exmaple.test.,这些都是可以的。但如果你不写任何其它内容,只有一个*,那就表示匹配所有的东西。
** 匹配任意长度字符,并且包含包名分隔符(.)。比如proguard-android.txt中使用的-dontwarn android.support.**就可以匹配android.support包下的所有内容,包括任意长度的子包。
匹配任意参数类型。比如void set*()就能匹配任意传入的参数类型, get*()就能匹配任意返回值的类型。
匹配任意长度的任意类型参数。比如void test(…)就能匹配任意void test(String a)或者是void test(int a, String b)这些方法。

Android混淆的通用规则

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

1,系统混淆配置

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

2,常用的一些混淆配置

-keepattributes Signature #范型
#native方法不混淆
-keepclasseswithmembernames class * {
    native <methods>;
}
#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.* <fields>;
}
-keepclasseswithmembernames class * {
    @butterknife.* <methods>;
}

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

-keepclassmembers class * {
   public <init> (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.**{*;}
发布了49 篇原创文章 · 获赞 41 · 访问量 18万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章