android用proGuard代码混淆
2018-01-19 10:43
323 查看
简介
因为java是一门跨平台语言,java虚拟机会把java源代码编译成.class文件,从而各种软件可对.class文件进行反编译,造成代码不安全,以至于android引入了proGuard对.class文件进行混淆。目录
proguard是什么?proguard技术的功能
proguard工作原理
proguard在android中的运用
proguard是什么?
proguard工具是用于压缩,优化,混淆我们.class文件的代码,主要作用是可以将代码中的无用类,字段,方法和属性同时进行混淆
proguard技术功能
压缩(Shrink):检测并移除代码中的无用的类,字段,方法和属性。
优化(Optimize):对字节码进行优化,移除无用的指令。
混淆(Obfuscate):对于一些无意义的名称(a,b,c),对类,字段和方法进行重命名。
预检(Preveirfy):在Java平台上对处理后的代码进行预检,确保加载的class文件是可执行的。
总结:Proguard是一个Java类文件压缩器、优化器、混淆器、预校验器。这些步骤让代码更精简,更高效,也更难被逆向(破解)。
proguard工作原理
ProGuard是由shrink->optimize->obfuscate->preverify几个步骤组成的,每个步骤可以独立开来的,我们可用脚本来决定执行其中的哪几个步骤。
ProGuard又是怎么知道这个代码没有被用到呢?
这里引入一个Entry Point的概念,Entry Point是在ProGuard过程中不会被处理的类或方法。在压缩的步骤中,ProGuard会从上述的Entry Point开始递归遍历,搜索哪些类和类的成员在使用,对于没有被使用的类和类的成员,就会在压缩段丢弃,在接下来的优化过程中,那些非Entry Point的类、方法都会被设置为private、static或final,不使用的参数会被移除,此外,有些方法会被标记为内联的,在混淆的步骤中,ProGuard会对非Entry Point的类和方法进行重命名。
proguard在android中的运用
我们可以从三个步骤进行混淆:
1.基本混淆
2.针对AppModule进行混淆
3.针对第三方进行混淆
1.基本混淆
android sdk 的 /sdk/tools/proguard/proguard-android.txt 中已经提供了基本的混淆配置,不需要在 proguard-rules.pro 中重复配置。
# 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 # 不混淆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的所有类的set和get方法 -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的方法 -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 -keepclassmembers class * implements android.os.Parcelable { public static final android.os.Parcelable$Creator CREATOR; } # 不混淆R类中所有static字段 -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. # 忽略兼容库的所有警告 -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>(...); }
针对Appmodule进行混淆,可在proguard-rule.pro进行常用的配置
#指定代码的压缩级别 -optimizationpasses 5 # 混淆时所采用的算法 -optimizations !code/simplification/arithmetic,!field/*,!class/merging/* #记录生成的日志数据,gradle build时在本项目根目录输出 #apk 包内所有 class 的内部结构 -dump class_files.txt #未混淆的类和成员 -printseeds seeds.txt #列出从 apk 中删除的代码 -printusage unused.txt #混淆前后的映射 -printmapping mapping.txt #移除log代码 -assumenosideeffects class android.util.Log { public static *** v(...); public static *** i(...); public static *** d(...); public static *** w(...); public static *** e(...); } #不混淆反射用到的类 -keepattributes Signature -keepattributes EnclosingMethod #保持继承自系统类的class不被混淆 -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 interface android.support.v4.app.** { *; } -keep class android.support.v4.** { *; } -keep public class * extends android.support.v4.** -keep interface android.support.v7.app.** { *; } -keep class android.support.v7.** { *; } -keep public class * extends android.support.v7.** -keep public class * extends android.app.Fragment -keep class * extends android.**{*;} #不混淆Serializable接口的子类中指定的某些成员变量和方法 -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(); } ############ 不混淆引用的jar ############ #不混淆butterknife -keepclasseswithmembernames class * { @butterknife.* <fields>; } -keepclasseswithmembernames class * { @butterknife.* <methods>; } -dontwarn butterknife.internal.** ############ 保持自定义控件不被混淆 ############ -keepclasseswithmembernames class * { public <init>(android.content.Context); } -keepclasseswithmembernames class * { public <init>(android.content.Context, android.util.AttributeSet); } -keepclasseswithmembernames class * { public <init>(android.content.Context, android.util.AttributeSet, int); } -keepclasseswithmembernames class * { public <init>(android.content.Context, android.util.AttributeSet, int, int); } #不混淆整个包 #-keep class com.test.test.**{*;} #不混淆对外接口的public类名和成员名,否则外部无法调用 #-keep public interface com.test.test.**{*;} #-keep public enum com.test.test.**{*;} #-keep public class com.test.test.**{ # public *; #} # 对WebView的处理 -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, java.lang.String) } # 保留JS方法不被混淆 -keepclassmembers class com.example.xxx.MainActivity$JSInterface1 { <methods>; } # 对于第三方包进行混淆,一般都在各自的文档有表明,在这里只需要复制即可 # 对alipay的混淆处理 -libraryjars libs/alipaysdk.jar -dontwarn com.alipay.android.app.** -keep public class com.alipay.** { *; }
总结:
以上就是android对于代码混淆的过程,我们的测试工作也要基于混淆包进行,这样才能尽早发现问题。
相关文章推荐
- Android 2.3 代码混淆proguard技术介绍
- android 混淆(proguard)代码-简单版
- Android proguard 混淆代码
- 在android中使用proguard混淆代码出现“Conversion to Dalvik format failed with error 1”错误的解决方法
- 【Android】【代码混淆】ProGuard
- android 代码混淆proguard
- Android 项目的代码混淆,Android proguard 使用说明
- Android库工程及代码混淆(project.properties、proguard-project.txt)
- Android混淆代码工具ProGuard
- 使用proguard对Android Library中代码进行混淆
- Android 编程下的代码混淆proguard
- 利用android proguard混淆代码
- Android ProGuard代码混淆
- Android 项目的代码混淆,Android proguard 使用说明
- 转载:混淆包含SlidingMenu、gson等Android代码的proguard写法
- 用ProGuard混淆Android代码
- 日积月累:Proguard进行Android代码混淆
- Android项目proguard代码混淆遇到的一系列问题,外部jar,Gson包等
- android混淆代码-proguard
- 如何混淆Android项目代码(ProGuard),防止反编译