混淆:
android代码混淆主要用到android SDK 提供的ProGuard工具。它使用简单无意义的名字来重命名你的类名、字段名和方法名。经过以上操作的jar文件会变得更小,并很难进行逆向工程。
proguard配置:
1.使用系统生成的混淆文件进行混淆打包:在project.properties文件中配置proguard.config = proguard.cfg但只能混淆不含第三方包的工程。在我们的项目中大量的使用第三方包,因此我们要自定义混淆文件。
2.使用自定义在project.properties文件中指定混淆的文件 proguard.config = proguard-project.txt。
在缺省的情况下,proguard会混淆所有的代码,因此在混淆中需要用到如下的一些关键字:
-keep 保留类和类成员不被混淆,
-dontwarn 告知proguard不发出警告(缺省proguard会检查每一个引用是否正确,但是第三方库里面往往有些不会用到的类,没有正确引用。如果不配置的话,系统就会报错。)
-keepclassmembers指定的类成员被保留。
-keepclasseswithmembers指定的类和类成员被保留,假如指定的类成员存在的话
混淆的相关语法:
-optimizationpasses 5
-dontusemixedcaseclassnames 【混淆时不会产生形形色色的类名 】
-dontskipnonpubliclibraryclasses 【指定不去忽略非公共的库类。 】
-dontpreverify 【不预校验】
优化
-dontoptimize 不优化输入的类文件
-verbose
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/* 【优化】
-keep public class * extends android.app.Activity 【不进行混淆类名的类,保持其原类名和包名】
-keep public abstract interface com.asqw.android.Listener{
public protected <methods>; 【全部public protected的方法名不进行混淆】
}
-keep public class com.asqw.android{
public void Start(java.lang.String); 【对该方法不进行混淆】
}
-keepclasseswithmembernames class * { 【对全部类的native方法名不进行混淆】
native <methods>;
}
-keepclasseswithmembers class * { 【对全部类的指定方法的方法名不进行混淆】
public <init>(android.content.Context, android.util.AttributeSet);
}
-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接口的全部类的类名 不进行混淆,对其成员变量为Parcelable$Creator类型的成员变量的变量名不进行混淆】
public static final android.os.Parcelable$Creator *;
}
-keepclasseswithmembers class org.jboss.netty.util.internal.LinkedTransferQueue {【对指定类的指定变量的变量名不进行混淆】
volatile transient org.jboss.netty.util.internal.LinkedTransferQueue$Node head;
volatile transient org.jboss.netty.util.internal.LinkedTransferQueue$Node tail;
volatile transient int sweepVotes;
}
-keep public class com.unionpay.** {*; }【对com.unionpay包下全部的类都不进行混淆,即不混 淆类名,也不混淆方法名和变量名】
-keepclasseswithmembers class * {# 保持自定义控件类不被混淆
public <init>(android.content.Context, android.util.AttributeSet);
}
-keepclasseswithmembers class * {# 保持自定义控件类不被混淆
public <init>(android.content.Context, android.util.AttributeSet, int);
}
-keepclassmembers class * extends android.app.Activity {# 保持自定义控件类不被混淆
public void *(android.view.View);
}
常见第三方类库的混淆流程:
1.首先加入-dontwarn增大混淆的成功率;例如:-dontwarn android.support.v4.**
2.指明lib在工程中的路径-libraryjars后面跟要编译in.jar的其它类包,如果是多个,用多行列出
-libraryjars libs/gson-2.2.2.jar
3.引入后,对项目使用到的入口类进行指定,-keep 后跟项目的 入口类
-keep class universal-image-loader-1.8.4-with-sources.** { *; }
-keep interface universal-image-loader-1.8.4-with-sources.** { *; }
-keep class lockSDK_3.3.** { *; }
-keep interface lockSDK_3.3.** { *; }
-keep class MobileProbe.jar.** { *; }
-keep interface MobileProbe.jar.** { *; }
-keep class android.net.http.SslError
-keep class android.webkit.**{*;}
-keep class cn.sharesdk.**{*;}
-keep class com.sina.**{*;}
keep就是 告诉proguard不用混淆这个包里面的类
常见的不能混淆的android code
Android 程序,下面这样代码混淆的时候要注意保留。
Android系统组件,系统组件有固定的方法被系统调用。
被Android Resource 文件引用到的。名字已经固定,也不能混淆,比如自定义的View 。
Android Parcelable ,需要使用android 序列化的。
其他Anroid 官方建议不混淆的,如
android.app.backup.BackupAgentHelper
android.preference.Preference
com.android.vending.licensing.ILicensingService
Java序列化方法,系统序列化需要固定的方法。
枚举 ,系统需要处理枚举的固定方法。
本地方法,不能修改本地方法名
annotations 注释
数据库驱动
有些resource 文件
用到反射的地方
ProGuard对文件路径的名名很有讲究,不支持括号,也不支持空格
尽量不要去混淆实体Modle
用到反射的类和方法不要混淆
只有在生成release版本的apk时,混淆配置才会起作用,debug版本的apk不会进行混淆。