Android混淆


转载:https://www.jianshu.com/p/7436a1a32891

           https://blog.csdn.net/olevin/article/details/52876821

简介

作为Android开发者,如果你不想开源你的应用,那么在应用发布前,就需要对代码进行混淆处理,从而让我们代码即使被反编译,也难以阅读。混淆概念虽然容易,但很多初学者也只是网上搜一些成型的混淆规则粘贴进自己项目,并没有对混淆有个深入的理解。本篇文章的目的就是让一个初学者在看完后,能在不进行任何帮助的情况下,独立写出适合自己代码的混淆规则。

说在前面

这里我们直接用Android Studio来说明如何进行混淆,Android Studio自身集成Java语言的ProGuard作为压缩,优化和混淆工具,配合Gradle构建工具使用很简单,只需要在工程应用目录的gradle文件中设置minifyEnabled为true即可。然后我们就可以到proguard-rules.pro文件中加入我们的混淆规则了。

android {
    ...
    buildTypes {
        release {
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

以上示例代码表示对release版本就行混淆处理。下面我们先来简介下ProGuard的三大作用,并简要说明下它们常用的命令。


ProGuard作用

 

 

压缩(Shrinking):默认开启,用以减小应用体积,移除未被使用的类和成员,并且会在优化动作执行之后再次执行(因为优化后可能会再次暴露一些未被使用的类和成员)。

-dontshrink 关闭压缩

优化(Optimization):默认开启,在字节码级别执行优化,让应用运行的更快。

-dontoptimize  关闭优化
-optimizationpasses n 表示proguard对代码进行迭代优化的次数,Android一般为5

混淆(Obfuscation):默认开启,增大反编译难度,类和类成员会被随机命名,除非用keep保护。

-dontobfuscate 关闭混淆

混淆后默认会在工程目录app/build/outputs/mapping/release下生成一个mapping.txt文件,这就是混淆规则,我们可以根据这个文件把混淆后的代码反推回源本的代码,所以这个文件很重要,注意保护好。原则上,代码混淆后越乱越无规律越好,但有些地方我们是要避免混淆的,否则程序运行就会出错,所以就有了下面我们要教大家的,如何让自己的部分代码避免混淆从而防止出错。

基本规则

先看如下两个比较常用的命令,很多童鞋可能会比较迷惑以下两者的区别。


-keep class cn.hadcn.test.**
-keep class cn.hadcn.test.*

一颗星表示只是保持该包下的类名,而子包下的类名还是会被混淆;两颗星表示把本包和所含子包下的类名都保持;用以上方法保持类后,你会发现类名虽然未混淆,但里面的具体方法和变量命名还是变了,这时如果既想保持类名,又想保持里面的内容不被混淆,我们就需要以下方法了

-keep class cn.hadcn.test.* {*;}

在此基础上,我们也可以使用Java的基本规则来保护特定类不被混淆,比如我们可以用extendimplement等这些Java规则。如下例子就避免所有继承Activity的类被混淆

-keep public class * extends android.app.Activity

如果我们要保留一个类中的内部类不被混淆则需要用$符号,如下例子表示保持ScriptFragment内部类JavaScriptInterface中的所有public内容不被混淆。


-keepclassmembers class cc.ninty.chat.ui.fragment.ScriptFragment$JavaScriptInterface {
   public *;
}

再者,如果一个类中你不希望保持全部内容不被混淆,而只是希望保护类下的特定内容,就可以使用


<init>;     //匹配所有构造器
<fields>;   //匹配所有域
<methods>;  //匹配所有方法方法

你还可以在<fields><methods>前面加上privatepublicnative等来进一步指定不被混淆的内容,如


-keep class cn.hadcn.test.One {
    public <methods>;
}

表示One类下的所有public方法都不会被混淆,当然你还可以加入参数,比如以下表示用JSONObject作为入参的构造函数不会被混淆


-keep class cn.hadcn.test.One {
   public <init>(org.json.JSONObject);
}

有时候你是不是还想着,我不需要保持类名,我只需要把该类下的特定方法保持不被混淆就好,那你就不能用keep方法了,keep方法会保持类名,而需要用keepclassmembers ,如此类名就不会被保持,为了便于对这些规则进行理解,官网给出了以下表格

保留防止被移除或者被重命名防止被重命名
类和类成员-keep-keepnames
仅类成员-keepclassmembers-keepclassmembernames
如果拥有某成员,保留类和类成员-keepclasseswithmembers-keepclasseswithmembernames

移除是指在压缩(Shrinking)时是否会被删除。以上内容时混淆规则中需要重点掌握的,了解后,基本所有的混淆规则文件你应该都能看懂了。再配合以下几点注意事项,开启你为自己代码,实现混淆规则之旅吧。

注意事项

1,jni方法不可混淆,因为这个方法需要和native方法保持一致;


-keepclasseswithmembernames class * { # 保持native方法不被混淆    
    native <methods>;
}

2,反射用到的类不混淆(否则反射可能出现问题);

3,AndroidMainfest中的类不混淆,所以四大组件和Application的子类和Framework层下所有的类默认不会进行混淆。自定义的View默认也不会被混淆;所以像网上贴的很多排除自定义View,或四大组件被混淆的规则在Android Studio中是无需加入的;

4,与服务端交互时,使用GSON、fastjson等框架解析服务端数据时,所写的JSON对象类不混淆,否则无法将JSON解析成对应的对象;

5,使用第三方开源库或者引用其他第三方的SDK包时,如果有特别要求,也需要在混淆文件中加入对应的混淆规则;

6,有用到WebView的JS调用也需要保证写的接口方法不混淆,原因和第一条一样;

7,Parcelable的子类和Creator静态成员变量不混淆,否则会产生Android.os.BadParcelableException异常;


-keep class * implements Android.os.Parcelable { # 保持Parcelable不被混淆           
    public static final Android.os.Parcelable$Creator *;
}

8,使用enum类型时需要注意避免以下两个方法混淆,因为enum类的特殊性,以下两个方法会被反射调用,见第二条规则。


-keepclassmembers enum * {  
    public static **[] values();  
    public static ** valueOf(java.lang.String);  
}

混淆模板及常用第三方混淆

 

[python] view plain copy

  1. #############################################  
  2. #  
  3. # 对于一些基本指令的添加  
  4. #  
  5. #############################################  
  6. # 代码混淆压缩比,在0~7之间,默认为5,一般不做修改  
  7. -optimizationpasses 5  
  8.   
  9. # 混合时不使用大小写混合,混合后的类名为小写  
  10. -dontusemixedcaseclassnames  
  11.   
  12. # 指定不去忽略非公共库的类  
  13. -dontskipnonpubliclibraryclasses  
  14.   
  15. # 这句话能够使我们的项目混淆后产生映射文件  
  16. # 包含有类名->混淆后类名的映射关系  
  17. -verbose  
  18.   
  19. # 指定不去忽略非公共库的类成员  
  20. -dontskipnonpubliclibraryclassmembers  
  21.   
  22. # 不做预校验,preverify是proguard的四个步骤之一,Android不需要preverify,去掉这一步能够加快混淆速度。  
  23. -dontpreverify  
  24.   
  25. # 保留Annotation不混淆  
  26. -keepattributes *Annotation*,InnerClasses  
  27.   
  28. # 避免混淆泛型  
  29. -keepattributes Signature  
  30.   
  31. # 抛出异常时保留代码行号  
  32. -keepattributes SourceFile,LineNumberTable  
  33.   
  34. # 指定混淆是采用的算法,后面的参数是一个过滤器  
  35. # 这个过滤器是谷歌推荐的算法,一般不做更改  
  36. -optimizations !code/simplification/cast,!field/*,!class/merging/*  
  37.   
  38.   
  39. #############################################  
  40. #  
  41. # Android开发中一些需要保留的公共部分  
  42. #  
  43. #############################################  
  44.   
  45. # 保留我们使用的四大组件,自定义的Application等等这些类不被混淆  
  46. # 因为这些子类都有可能被外部调用  
  47. -keep public class * extends android.app.Activity  
  48. -keep public class * extends android.app.Appliction  
  49. -keep public class * extends android.app.Service  
  50. -keep public class * extends android.content.BroadcastReceiver  
  51. -keep public class * extends android.content.ContentProvider  
  52. -keep public class * extends android.app.backup.BackupAgentHelper  
  53. -keep public class * extends android.preference.Preference  
  54. -keep public class * extends android.view.View  
  55. -keep public class com.android.vending.licensing.ILicensingService  
  56.   
  57.   
  58. # 保留support下的所有类及其内部类  
  59. -keep class android.support.** {*;}  
  60.   
  61. # 保留继承的  
  62. -keep public class * extends android.support.v4.**  
  63. -keep public class * extends android.support.v7.**  
  64. -keep public class * extends android.support.annotation.**  
  65.   
  66. # 保留R下面的资源  
  67. -keep class **.R$* {*;}  
  68.   
  69. # 保留本地native方法不被混淆  
  70. -keepclasseswithmembernames class * {  
  71.     native <methods>;  
  72. }  
  73.   
  74. # 保留在Activity中的方法参数是view的方法,  
  75. # 这样以来我们在layout中写的onClick就不会被影响  
  76. -keepclassmembers class * extends android.app.Activity{  
  77.     public void *(android.view.View);  
  78. }  
  79.   
  80. # 保留枚举类不被混淆  
  81. -keepclassmembers enum * {  
  82.     public static **[] values();  
  83.     public static ** valueOf(java.lang.String);  
  84. }  
  85.   
  86. # 保留我们自定义控件(继承自View)不被混淆  
  87. -keep public class * extends android.view.View{  
  88.     *** get*();  
  89.     void set*(***);  
  90.     public <init>(android.content.Context);  
  91.     public <init>(android.content.Context, android.util.AttributeSet);  
  92.     public <init>(android.content.Context, android.util.AttributeSet, int);  
  93. }  
  94.   
  95. # 保留Parcelable序列化类不被混淆  
  96. -keep class * implements android.os.Parcelable {  
  97.     public static final android.os.Parcelable$Creator *;  
  98. }  
  99.   
  100. # 保留Serializable序列化的类不被混淆  
  101. -keepclassmembers class * implements java.io.Serializable {  
  102.     static final long serialVersionUID;  
  103.     private static final java.io.ObjectStreamField[] serialPersistentFields;  
  104.     !static !transient <fields>;  
  105.     !private <fields>;  
  106.     !private <methods>;  
  107.     private void writeObject(java.io.ObjectOutputStream);  
  108.     private void readObject(java.io.ObjectInputStream);  
  109.     java.lang.Object writeReplace();  
  110.     java.lang.Object readResolve();  
  111. }  
  112.   
  113. # 对于带有回调函数的onXXEvent、**On*Listener的,不能被混淆  
  114. -keepclassmembers class * {  
  115.     void *(**On*Event);  
  116.     void *(**On*Listener);  
  117. }  
  118.   
  119. # webView处理,项目中没有使用到webView忽略即可  
  120. -keepclassmembers class fqcn.of.javascript.interface.for.webview {  
  121.     public *;  
  122. }  
  123. -keepclassmembers class * extends android.webkit.webViewClient {  
  124.     public void *(android.webkit.WebView, java.lang.String, android.graphics.Bitmap);  
  125.     public boolean *(android.webkit.WebView, java.lang.String);  
  126. }  
  127. -keepclassmembers class * extends android.webkit.webViewClient {  
  128.     public void *(android.webkit.webView, jav.lang.String);  
  129. }  
  130.   
  131. # 移除Log类打印各个等级日志的代码,打正式包的时候可以做为禁log使用,这里可以作为禁止log打印的功能使用  
  132. # 记得proguard-android.txt中一定不要加-dontoptimize才起作用  
  133. # 另外的一种实现方案是通过BuildConfig.DEBUG的变量来控制  
  134. #-assumenosideeffects class android.util.Log {  
  135. #    public static int v(...);  
  136. #    public static int i(...);  
  137. #    public static int w(...);  
  138. #    public static int d(...);  
  139. #    public static int e(...);  
  140. #}  
  141.   
  142. #############################################  
  143. #  
  144. # 项目中特殊处理部分  
  145. #  
  146. #############################################  
  147.   
  148. #-----------处理反射类---------------  
  149.   
  150.   
  151.   
  152. #-----------处理js交互---------------  
  153.   
  154.   
  155.   
  156. #-----------处理实体类---------------  
  157. # 在开发的时候我们可以将所有的实体类放在一个包内,这样我们写一次混淆就行了。  
  158. #-keep public class com.ljd.example.entity.** {  
  159. #    public void set*(***);  
  160. #    public *** get*();  
  161. #    public *** is*();  
  162. #}  
  163.   
  164.   
  165. #-----------处理第三方依赖库---------  

 

下面介绍常用第三方混淆配置:

 

[python] view plain copy

  1. # AndroidEventBus  
  2. -keep class org.simple.** { *; }  
  3. -keep interface org.simple.** { *; }  
  4. -keepclassmembers class * {  
  5.     @org.simple.eventbus.Subscriber <methods>;  
  6. }  
  7.   
  8.   
  9. # 百度地图(jar包换成自己的版本,记得签名要匹配)  
  10. -libraryjars libs/baidumapapi_v2_1_3.jar  
  11. -keep class com.baidu.** {*;}  
  12. -keep class vi.com.** {*;}  
  13. -keep class com.sinovoice.** {*;}  
  14. -keep class pvi.com.** {*;}  
  15. -dontwarn com.baidu.**  
  16. -dontwarn vi.com.**  
  17. -dontwarn pvi.com.**  
  18.   
  19.   
  20. # Bugly  
  21. -dontwarn com.tencent.bugly.**  
  22. -keep class com.tencent.bugly.** {*;}  
  23.   
  24.   
  25. # ButterKnife  
  26. -keep class butterknife.** { *; }  
  27. -dontwarn butterknife.internal.**  
  28. -keep class **$$ViewBinder { *; }   
  29. -keepclasseswithmembernames class * {  
  30.     @butterknife.* <fields>;  
  31. }  
  32. -keepclasseswithmembernames class * {  
  33.     @butterknife.* <methods>;  
  34. }  
  35.   
  36.   
  37. # EventBus  
  38. -keepattributes *Annotation*  
  39. -keepclassmembers class ** {  
  40.     @org.greenrobot.eventbus.Subscribe <methods>;  
  41. }  
  42. -keep enum org.greenrobot.eventbus.ThreadMode { *; }  
  43.   
  44.   
  45. # Facebook  
  46. -keep class com.facebook.** {*;}  
  47. -keep interface com.facebook.** {*;}  
  48. -keep enum com.facebook.** {*;}  
  49.   
  50.   
  51. # FastJson  
  52. -dontwarn com.alibaba.fastjson.**  
  53. -keep class com.alibaba.fastjson.** { *; }  
  54. -keepattributes Signature  
  55. -keepattributes *Annotation*  
  56.   
  57.   
  58. # Fresco  
  59. -keep class com.facebook.fresco.** {*;}  
  60. -keep interface com.facebook.fresco.** {*;}  
  61. -keep enum com.facebook.fresco.** {*;}  
  62.   
  63.   
  64. # 高德相关依赖  
  65. # 集合包:3D地图3.3.2 导航1.8.0 定位2.5.0  
  66. -dontwarn com.amap.api.**  
  67. -dontwarn com.autonavi.**  
  68. -keep class com.amap.api.**{*;}  
  69. -keep class com.autonavi.**{*;}  
  70. # 地图服务  
  71. -dontwarn com.amap.api.services.**  
  72. -keep class com.map.api.services.** {*;}  
  73. # 3D地图  
  74. -dontwarn com.amap.api.mapcore.**  
  75. -dontwarn com.amap.api.maps.**  
  76. -dontwarn com.autonavi.amap.mapcore.**  
  77. -keep class com.amap.api.mapcore.**{*;}  
  78. -keep class com.amap.api.maps.**{*;}  
  79. -keep class com.autonavi.amap.mapcore.**{*;}  
  80. # 定位  
  81. -dontwarn com.amap.api.location.**  
  82. -dontwarn com.aps.**  
  83. -keep class com.amap.api.location.**{*;}  
  84. -keep class com.aps.**{*;}  
  85. # 导航  
  86. -dontwarn com.amap.api.navi.**  
  87. -dontwarn com.autonavi.**  
  88. -keep class com.amap.api.navi.** {*;}  
  89. -keep class com.autonavi.** {*;}  
  90.   
  91.   
  92. # Glide  
  93. -keep public class * implements com.bumptech.glide.module.GlideModule  
  94. -keep public enum com.bumptech.glide.load.resource.bitmap.ImageHeaderParser$** {  
  95.   **[] $VALUES;  
  96.   public *;  
  97. }  
  98.   
  99.   
  100. # Gson  
  101. -keepattributes Signature-keepattributes *Annotation*  
  102. -keep class sun.misc.Unsafe { *; }  
  103. -keep class com.google.gson.stream.** { *; }  
  104. # 使用Gson时需要配置Gson的解析对象及变量都不混淆。不然Gson会找不到变量。  
  105. # 将下面替换成自己的实体类  
  106. -keep class com.example.bean.** { *; }  
  107.   
  108.   
  109. # Jackson  
  110. -dontwarn org.codehaus.jackson.**  
  111. -dontwarn com.fasterxml.jackson.databind.**  
  112. -keep class org.codehaus.jackson.** { *;}  
  113. -keep class com.fasterxml.jackson.** { *; }  
  114.   
  115.   
  116. # 极光推送  
  117. -dontoptimize  
  118. -dontpreverify  
  119. -dontwarn cn.jpush.**  
  120. -keep class cn.jpush.** { *; }  
  121.   
  122.   
  123. # OkHttp  
  124. -keep class com.squareup.okhttp.** { *; }  
  125. -keep interface com.squareup.okhttp.** { *; }  
  126. -dontwarn com.squareup.okhttp.**  
  127.   
  128.   
  129. # OkHttp3  
  130. -dontwarn com.squareup.okhttp3.**  
  131. -keep class com.squareup.okhttp3.** { *;}  
  132. -dontwarn okio.**  
  133.   
  134.   
  135. # Okio  
  136. -dontwarn com.squareup.**    
  137. -dontwarn okio.**    
  138. -keep public class org.codehaus.* { *; }    
  139. -keep public class java.nio.* { *; }  
  140.   
  141.   
  142. # OrmLite  
  143. -keepattributes *DatabaseField*   
  144. -keepattributes *DatabaseTable*   
  145. -keepattributes *SerializedName*    
  146. -keep class com.j256.**  
  147. -keepclassmembers class com.j256.** { *; }  
  148. -keep enum com.j256.**  
  149. -keepclassmembers enum com.j256.** { *; }  
  150. -keep interface com.j256.**  
  151. -keepclassmembers interface com.j256.** { *; }  
  152.   
  153.   
  154. # Realm  
  155. -keep class io.realm.annotations.RealmModule  
  156. -keep @io.realm.annotations.RealmModule class *  
  157. -keep class io.realm.internal.Keep  
  158. -keep @io.realm.internal.Keep class * { *; }  
  159. -dontwarn javax.**  
  160. -dontwarn io.realm.**  
  161.   
  162.   
  163. # Retrofit  
  164. -dontwarn retrofit2.**  
  165. -keep class retrofit2.** { *; }  
  166. -keepattributes Signature  
  167. -keepattributes Exceptions  
  168.   
  169.   
  170. # Retrolambda  
  171. -dontwarn java.lang.invoke.*  
  172.   
  173.   
  174. # RxJava RxAndroid  
  175. -dontwarn sun.misc.**  
  176. -keepclassmembers class rx.internal.util.unsafe.*ArrayQueue*Field* {  
  177.     long producerIndex;  
  178.     long consumerIndex;  
  179. }  
  180. -keepclassmembers class rx.internal.util.unsafe.BaseLinkedQueueProducerNodeRef {  
  181.     rx.internal.util.atomic.LinkedQueueNode producerNode;  
  182. }  
  183. -keepclassmembers class rx.internal.util.unsafe.BaseLinkedQueueConsumerNodeRef {  
  184.     rx.internal.util.atomic.LinkedQueueNode consumerNode;  
  185. }  
  186.   
  187.   
  188. # Universal-Image-Loader-v1.9.5  
  189. -libraryjars libs/universal-image-loader-1.9.5-SNAPSHOT-with-sources.jar  
  190. -dontwarn com.nostra13.universalimageloader.**  
  191. -keep class com.nostra13.universalimageloader.** { *; }  
  192.   
  193.   
  194. # 微信支付  
  195. -dontwarn com.tencent.mm.**  
  196. -dontwarn com.tencent.wxop.stat.**  
  197. -keep class com.tencent.mm.** {*;}  
  198. -keep class com.tencent.wxop.stat.**{*;}  
  199.   
  200.   
  201. # 信鸽  
  202. -keep public class * extends android.app.Service  
  203. -keep public class * extends android.content.BroadcastReceiver  
  204. -keep class com.tencent.android.tpush.**  {* ;}  
  205. -keep class com.tencent.mid.**  {* ;}  
  206. -keepattributes *Annotation*  
  207.   
  208.   
  209. # 新浪微博  
  210. -keep class com.sina.weibo.sdk.* { *; }    
  211. -keep class android.support.v4.* { *; }    
  212. -keep class com.tencent.* { *; }    
  213. -keep class com.baidu.* { *; }    
  214. -keep class lombok.ast.ecj.* { *; }    
  215. -dontwarn android.support.v4.**    
  216. -dontwarn com.tencent.**s    
  217. -dontwarn com.baidu.**    
  218.   
  219.   
  220. # 讯飞语音  
  221. -dontwarn com.iflytek.**  
  222. -keep class com.iflytek.** {*;}  
  223.   
  224.   
  225. # xUtils3.0  
  226. -keepattributes Signature,Annotation  
  227. -keep public class org.xutils.** {  
  228. public protected *;  
  229. }  
  230. -keep public interface org.xutils.** {  
  231. public protected *;  
  232. }  
  233. -keepclassmembers class * extends org.xutils.** {  
  234. public protected *;  
  235. }  
  236. -keepclassmembers @org.xutils.db.annotation.* class * {;}  
  237. -keepclassmembers @org.xutils.http.annotation. class * {*;}  
  238. -keepclassmembers class * {  
  239. @org.xutils.view.annotation.Event ;  
  240. }  
  241.   
  242.   
  243. # 银联  
  244. -dontwarn com.unionpay.**  
  245. -keep class com.unionpay.** { *; }  
  246.   
  247.   
  248. # 友盟统计分析  
  249. -keepclassmembers class * { public <init>(org.json.JSONObject); }  
  250. -keepclassmembers enum com.umeng.analytics.** {  
  251.     public static **[] values();  
  252.     public static ** valueOf(java.lang.String);  
  253. }  
  254.   
  255.   
  256. # 友盟自动更新  
  257. -keepclassmembers class * { public <init>(org.json.JSONObject); }  
  258. -keep public class cn.irains.parking.cloud.pub.R$*{ public static final int *; }  
  259. -keep public class * extends com.umeng.**  
  260. -keep class com.umeng.** { *; }  
  261.   
  262.   
  263. # 支付宝钱包  
  264. -dontwarn com.alipay.**  
  265. -dontwarn HttpUtils.HttpFetcher  
  266. -dontwarn com.ta.utdid2.**  
  267. -dontwarn com.ut.device.**  
  268. -keep class com.alipay.android.app.IAlixPay{*;}  
  269. -keep class com.alipay.android.app.IAlixPay$Stub{*;}  
  270. -keep class com.alipay.android.app.IRemoteServiceCallback{*;}  
  271. -keep class com.alipay.android.app.IRemoteServiceCallback$Stub{*;}  
  272. -keep class com.alipay.sdk.app.PayTask{ public *;}  
  273. -keep class com.alipay.sdk.app.AuthTask{ public *;}  
  274. -keep class com.alipay.mobilesecuritysdk.*  
  275. -keep class com.ut.*  






 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值