手记

Android 混淆配置及Proguard用法

引言

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

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

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

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

1530873026(1).jpg

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 <methods>;
}
-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 <init>(android.content.Context);
    public <init>(android.content.Context, android.util.AttributeSet);
    public <init>(android.content.Context, android.util.AttributeSet, int);
}
-keepclasseswithmembers class * {
    public <init>(android.content.Context, android.util.AttributeSet);
    public <init>(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 <fields>;
}
-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.* <methods>;
}
-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 <methods>;
}
-keep class rx.schedulers.ImmediateScheduler {
    public <methods>;
}
-keep class rx.schedulers.TestScheduler {
    public <methods>;
}
-keep class rx.schedulers.Schedulers {
    public static ** test();
}#butterknife-keep class butterknife.** { *; }
-dontwarn butterknife.internal.**
-keep class **$$ViewBinder { *; }
-keepclasseswithmembernames class * {
    @butterknife.* <fields>;
}
-keepclasseswithmembernames class * {
    @butterknife.* <methods>;
}# 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.**



作者:AFinalDream
链接:https://www.jianshu.com/p/a1c7d0d5f194


0人推荐
随时随地看视频
慕课网APP