Android 混淆配置及Proguard用法

引言

对于Android应用的混淆,网上有很多的资料,也有很多的相关案例和模板,相信大家也都比较熟悉。但是,对于一些公司要求混淆度比较高的,有的人就会比较犯难,因为网上的大多模块,并不能完成这个需求,那我们怎么能去最大程度上的给反编译者添加阅读难度呢,本文主要讲的是该方向的讲解。(本文不考虑加固这种方法,只是从混淆的角度来说,而且很简单,大家看完以后会豁然开朗的)

通过map实现自己的混淆需求

1.首先配置自定义混淆map文件,并配置到proguard-rules.pro文件中

首先创建一个 mapping.map 文件,然后在 proguard-rules.pro 文件中添加
-applymapping mapping.map 这句话。

Android 混淆配置及Proguard用法_第1张图片

2.具体的混淆语句编写及要求

  • 对类名进行混淆

com.xx.xx.xx -> com.a.a.a:

以上是对类名进行混淆的语句,com.xx.xx.xx 表示的是你需要混淆的类全路径, com.a.a.a表示的是你混淆后的别名。
注:配置的别名后的 “:” 冒号一定不能少。

  • 对变量进行混淆

java.lang.String usrname-> a

( 八大基本数据类型以外的类型)以上是对变量进行混淆的语句,java.lang.String 表示的是你要混淆的变量的类型路径,usrname 表示的是你要混淆的变量名称, a 表示的是你混淆后的别名。

int number -> b

( 八大基本数据类型) 以上是对变量进行混淆的语句,int 表示的是你要混淆的变量的类型,number 表示的是你要混淆的变量名称, b 表示的是你混淆后的别名。

注:对变量的混淆,需要注意的有两点:
1.混淆语句必须一行写完,假设如果过长,分两行来写,那么该混淆语句不会被执行混淆
2.对于变量的类型定义,分基本数据类型和引用数据类型,他们混淆定义的区别在于写法:基本数据类型可以直接写该类型进行定义,而引用数据类型需要写该数据类型的全路径进行定义,否则,会混淆失败

  • 对方法进行混淆

void push(android.app.Activity) -> a

以上是对方法进行混淆的语句,void 表示的是你要混淆的方法返回类型,push 表示的是你要混淆的方法名称, android.app.Activity 表示的是你要混淆的方法参数,a 表示的是你混淆后的别名。
注:对方法的混淆,需要注意的有两点:
1.混淆语句必须一行写完,假设如果过长,分两行来写,那么该混淆语句不会被执行混淆。
2.返回参数、方法传入参数如果是引用类型,也需要写该类型的全路径。

混淆通用模板

以下内容是网上最多的基本混淆模板,我就不进行解说了。

#-------------------------------------------基本不用动区域--------------------------------------------
#---------------------------------基本指令区----------------------------------
-optimizationpasses 5       # 指定代码的压缩级别
-dontusemixedcaseclassnames     # 是否使用大小写混合
-dontskipnonpubliclibraryclasses        # 指定不去忽略非公共的库类
-dontskipnonpubliclibraryclassmembers       # 指定不去忽略包可见的库类的成员
-dontpreverify      # 混淆时是否做预校验
-verbose        # 混淆时是否记录日志
-printmapping proguardMapping.txt
-optimizations !code/simplification/cast,!field/*,!class/merging/*      # 混淆时所采用的算法
-keepattributes *Annotation*,InnerClasses
-keepattributes Signature
-keepattributes SourceFile,LineNumberTable
#----------------------------------------------------------------------------
-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 * extends android.view.View
-keep public class com.android.vending.licensing.ILicensingService
-keep class android.support.** {*;}
#-ignorewarnings -keep class * { public private *; }

#如果有引用v4包可以添加下面这行
-keep class android.support.v4.** { *; }
-keep public class * extends android.support.v4.**
-keep public class * extends android.app.Fragment

-keepclasseswithmembernames class * {
    native ;
}
-keepclassmembers class * extends android.app.Activity{
    public void *(android.view.View);
}
-keepclassmembers enum * {
    public static **[] values();
    public static ** valueOf(java.lang.String);
}
-keep public class * extends android.view.View{
    *** get*();
    void set*(***);
    public (android.content.Context);
    public (android.content.Context, android.util.AttributeSet);
    public (android.content.Context, android.util.AttributeSet, int);
}
-keepclasseswithmembers class * {
    public (android.content.Context, android.util.AttributeSet);
    public (android.content.Context, android.util.AttributeSet, int);
}
-keep class * implements android.os.Parcelable {
  public static final android.os.Parcelable$Creator *;
}
-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();
}
#表示不混淆R文件中的所有静态字段
-keep class **.R$* {
    public static ;
}
-keepclassmembers class * {
    void *(**On*Event);
}
#----------------------------------------------------------------------------

#---------------------------------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);
}

一般以下情况都会不混淆:
1.使用了自定义控件那么要保证它们不参与混淆
2.使用了枚举要保证枚举不被混淆
3.对第三方库中的类不进行混淆
4.运用了反射的类也不进行混淆
5.使用了 Gson 之类的工具要使 JavaBean 类即实体类不被混淆
6.在引用第三方库的时候,一般会标明库的混淆规则的,建议在使用的时候就把混淆规则添加上去,免得到最后才去找
7.有用到 WebView 的 JS 调用也需要保证写的接口方法不混淆,原因和第一条一样
8.Parcelable 的子类和 Creator 静态成员变量不混淆,否则会产生 Android.os.BadParcelableException 异常
9.Android四大组件和Application最好也不要混淆

第三方库常用混淆

#---------------------------------2.第三方库---------------------------------
#okhttp3
-dontwarn com.squareup.okhttp3.**
-keep class com.squareup.okhttp3.** { *;}
-keep class okhttp3.** { *;}
-keep class okio.** { *;}
-dontwarn sun.security.**
-keep class sun.security.** { *;}
-dontwarn okio.**
-dontwarn okhttp3.**

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

# 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;
}
-dontnote rx.internal.util.PlatformDependent

# Retrofit, OkHttp, Gson
-keep class com.squareup.okhttp.** { *; }
-keep interface com.squareup.okhttp.** { *; }
-dontwarn com.squareup.okhttp.**
-dontwarn rx.**
-dontwarn retrofit.**
-keep class retrofit.** { *; }
-keepclasseswithmembers class * {
    @retrofit.http.* ;
}
-keep class sun.misc.Unsafe { *; }
-dontwarn java.nio.file.*
-dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement

# Rxjava-promises
-keep class com.darylteo.rx.** { *; }
-dontwarn com.darylteo.rx.**

# RxJava 0.21
-keep class rx.schedulers.Schedulers {
    public static ;
}
-keep class rx.schedulers.ImmediateScheduler {
    public ;
}
-keep class rx.schedulers.TestScheduler {
    public ;
}
-keep class rx.schedulers.Schedulers {
    public static ** test();
}

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

# RxLifeCycle2
-keep class com.trello.rxlifecycle2.** { *; }
-keep interface com.trello.rxlifecycle2.** { *; }
-dontwarn com.trello.rxlifecycle2.**

-keep class com.github.mikephil.charting.** { *; }
-dontwarn com.github.mikephil.charting.data.realm.**

福利

以下链接是个人觉得对混淆介绍比较有用的文章链接

http://www.imgeek.org/article/825308232
https://blog.csdn.net/double2hao/article/details/51277943
https://www.jianshu.com/p/b471db6a01af
https://blog.csdn.net/bihansheng2010/article/details/51353023

你可能感兴趣的:(android开发)