5分钟搞定android混淆

女爷i 2022-06-09 07:45 311阅读 0赞

前言

混淆是上线前挺重要的一个环节。android使用的ProGuard,可以起到压缩,混淆,预检,优化的作用。但是很多童鞋还没有掌握正确的写混淆文件的姿势。我希望搞个模板化的东西,让大家轻松搞定混淆。那么,开始写一个项目的混淆吧。。。我是不是很直接。。。。

五步搞定

1

打开项目中的proguard-rules.pro,将下面的代码复制进去。我的思路是将混淆分为2个主要部分

  • 定制化区域。这里边的内容是我们主要需要补充的部分,大致分为4个小部分,我们接下来的步骤主要是补充这4个部分的东西。
  • 基本不用动区域。顾名思义,基本不用动。这块的内容我已经写好了,除非有特殊的需求,基本不用改动。。。请叫我雷锋。。。。。

    —————————————————————-定制化区域———————————————————————

    ————————————————-1.实体类————————————————-

  1. #-------------------------------------------------------------------------
  2. #---------------------------------2.第三方包-------------------------------
  3. #-------------------------------------------------------------------------
  4. #---------------------------------3.与js互相调用的类------------------------
  5. #-------------------------------------------------------------------------
  6. #---------------------------------4.反射相关的类和方法-----------------------
  7. #----------------------------------------------------------------------------
  8. #---------------------------------------------------------------------------------------------------
  9. #-------------------------------------------基本不用动区域--------------------------------------------
  10. #---------------------------------基本指令区----------------------------------
  11. -optimizationpasses 5
  12. -dontusemixedcaseclassnames
  13. -dontskipnonpubliclibraryclasses
  14. -dontskipnonpubliclibraryclassmembers
  15. -dontpreverify
  16. -verbose
  17. -printmapping proguardMapping.txt
  18. -optimizations !code/simplification/cast,!field/*,!class/merging/*
  19. -keepattributes *Annotation*,InnerClasses
  20. -keepattributes Signature
  21. -keepattributes SourceFile,LineNumberTable
  22. #----------------------------------------------------------------------------
  23. #---------------------------------默认保留区---------------------------------
  24. -keep public class * extends android.app.Activity
  25. -keep public class * extends android.app.Application
  26. -keep public class * extends android.app.Service
  27. -keep public class * extends android.content.BroadcastReceiver
  28. -keep public class * extends android.content.ContentProvider
  29. -keep public class * extends android.app.backup.BackupAgentHelper
  30. -keep public class * extends android.preference.Preference
  31. -keep public class * extends android.view.View
  32. -keep public class com.android.vending.licensing.ILicensingService
  33. -keep class android.support.** {*;}
  34. -keepclasseswithmembernames class * {
  35. native <methods>;
  36. }
  37. -keepclassmembers class * extends android.app.Activity{
  38. public void *(android.view.View);
  39. }
  40. -keepclassmembers enum * {
  41. public static **[] values();
  42. public static ** valueOf(java.lang.String);
  43. }
  44. -keep public class * extends android.view.View{
  45. *** get*();
  46. void set*(***);
  47. public <init>(android.content.Context);
  48. public <init>(android.content.Context, android.util.AttributeSet);
  49. public <init>(android.content.Context, android.util.AttributeSet, int);
  50. }
  51. -keepclasseswithmembers class * {
  52. public <init>(android.content.Context, android.util.AttributeSet);
  53. public <init>(android.content.Context, android.util.AttributeSet, int);
  54. }
  55. -keep class * implements android.os.Parcelable {
  56. public static final android.os.Parcelable$Creator *;
  57. }
  58. -keepclassmembers class * implements java.io.Serializable {
  59. static final long serialVersionUID;
  60. private static final java.io.ObjectStreamField[] serialPersistentFields;
  61. private void writeObject(java.io.ObjectOutputStream);
  62. private void readObject(java.io.ObjectInputStream);
  63. java.lang.Object writeReplace();
  64. java.lang.Object readResolve();
  65. }
  66. -keep class **.R$* {
  67. *;
  68. }
  69. -keepclassmembers class * {
  70. void *(**On*Event);
  71. }
  72. #----------------------------------------------------------------------------
  73. #---------------------------------webview------------------------------------
  74. -keepclassmembers class fqcn.of.javascript.interface.for.Webview {
  75. public *;
  76. }
  77. -keepclassmembers class * extends android.webkit.WebViewClient {
  78. public void *(android.webkit.WebView, java.lang.String, android.graphics.Bitmap);
  79. public boolean *(android.webkit.WebView, java.lang.String);
  80. }
  81. -keepclassmembers class * extends android.webkit.WebViewClient {
  82. public void *(android.webkit.WebView, jav.lang.String);
  83. }
  84. #----------------------------------------------------------------------------
  85. #---------------------------------------------------------------------------------------------------

2

理解完战略级思想后,我们开始第一部分补充-实体类。实体类由于涉及到与服务端的交互,各种gson的交互如此等等,是要保留的。将你项目中实体类都拎出来,用以下语法进行保留。

  1. -keep class 你的实体类所在的包.** { *; }

如我的项目下类User的完整路径为:com.demo.login.bean.User, 那我的混淆如下

  1. #---------------------------------1.实体类---------------------------------
  2. -keep class com.demo.login.bean.** { *; }
  3. #-------------------------------------------------------------------------

当然你的实体类肯定不止这一个,请用上边的方式一一添加,如果你的实体类都在一个包下,那你就幸福了。

3

第2部分是第三方包。打开你的build.gradle文件,查看你用了哪些第三方的包。

  1. dependencies {
  2. compile 'com.github.bumptech.glide:glide:3.7.0'
  3. compile 'org.greenrobot:eventbus:3.0.0'
  4. }

我这里用了glide,eventbus。我去他们的官网把已经写好的混淆copy下来。

  1. #---------------------------------2.第三方包-------------------------------
  2. #eventBus
  3. -keepattributes *Annotation*
  4. -keepclassmembers class ** {
  5. @org.greenrobot.eventbus.Subscribe <methods>;
  6. }
  7. -keep enum org.greenrobot.eventbus.ThreadMode { *; }
  8. -keepclassmembers class * extends org.greenrobot.eventbus.util.ThrowableFailureEvent {
  9. <init>(java.lang.Throwable);
  10. }
  11. #glide
  12. -keep public class * implements com.bumptech.glide.module.GlideModule
  13. -keep public enum com.bumptech.glide.load.resource.bitmap.ImageHeaderParser$** {
  14. **[] $VALUES;
  15. public *;
  16. }
  17. #-------------------------------------------------------------------------

一般官网都是有混淆的,没有的话就google,也没有的话自己按照上面的写法自己写,还不会的话。。。。。只能换个包。。。。。如果你是直接包含的jar包的话,你这样写

  1. #---------------------------------2.第三方包-------------------------------
  2. #log4j
  3. -libraryjars log4j-1.2.17.jar
  4. -dontwarn org.apache.log4j.**
  5. -keep class org.apache.log4j.** { *;}
  6. #-------------------------------------------------------------------------

大致意思就是不混淆,不报warn。如果gradle报错的话,可以考虑注释掉-libraryjars log4j-1.2.17.jar这句。

4

第三部分与js互调的类,工程中没有直接跳过。一般你可以这样写

  1. -keep class 你的类所在的包.** { *; }

如果是内部类的话,你可以这样

  1. -keepclasseswithmembers class 你的类所在的包.父类$子类 { <methods>; }

例如

  1. -keepclasseswithmembers class com.demo.login.bean.ui.MainActivity$JSInterface {
  2. <methods>;
  3. }

5

第四部分与反射有关的类,工程中没有直接跳过。类的话直接这样

  1. -keep class 你的类所在的包.** { *; }

熟练后不用五分钟就能搞定。大家可以把自己写完混淆所用的时间写在评论里(0,0)

深入了解

先逐条介绍下基本指令区指令的含义

  1. -optimizationpasses 5

代码混淆的压缩比例,值在0-7之间

  1. -dontusemixedcaseclassnames

混淆后类名都为小写

  1. -dontskipnonpubliclibraryclasses

指定不去忽略非公共的库的类

  1. -dontskipnonpubliclibraryclassmembers

指定不去忽略非公共的库的类的成员

  1. -dontpreverify

不做预校验的操作

  1. -verbose
  2. -printmapping proguardMapping.txt

生成原类名和混淆后的类名的映射文件

  1. -optimizations !code/simplification/cast,!field/*,!class/merging/*

指定混淆是采用的算法

  1. -keepattributes *Annotation*,InnerClasses

不混淆Annotation

  1. -keepattributes Signature

不混淆泛型

  1. -keepattributes SourceFile,LineNumberTable

抛出异常时保留代码行号

基本指令区基本介绍完了,说下2条用的最多的指令

  1. -keep class XXXX

保留类名不变,也就是类名不混淆,而类中的成员名不保证。当然也可以是继承XXX类的所有类名不混淆,具体代码不贴了,重在理解。

  1. -keepclasseswithmembers class XXXX

保留类名和成员名。当然也可以是类中特定方法,代码不贴了,理由同上。

附:完整的混淆

  1. #-------------------------------------------定制化区域----------------------------------------------
  2. #---------------------------------1.实体类---------------------------------
  3. -keep class com.demo.login.bean.** { *; }
  4. -keep class com.demo.main.bean.** { *; }
  5. #-------------------------------------------------------------------------
  6. #---------------------------------2.第三方包-------------------------------
  7. #eventBus
  8. -keepattributes *Annotation*
  9. -keepclassmembers class ** {
  10. @org.greenrobot.eventbus.Subscribe <methods>;
  11. }
  12. -keep enum org.greenrobot.eventbus.ThreadMode { *; }
  13. -keepclassmembers class * extends org.greenrobot.eventbus.util.ThrowableFailureEvent {
  14. <init>(java.lang.Throwable);
  15. }
  16. #glide
  17. -keep public class * implements com.bumptech.glide.module.GlideModule
  18. -keep public enum com.bumptech.glide.load.resource.bitmap.ImageHeaderParser$** {
  19. **[] $VALUES;
  20. public *;
  21. }
  22. #log4j
  23. -libraryjars log4j-1.2.17.jar
  24. -dontwarn org.apache.log4j.**
  25. -keep class org.apache.log4j.** { *;}
  26. #-------------------------------------------------------------------------
  27. #---------------------------------3.与js互相调用的类------------------------
  28. -keepclasseswithmembers class com.demo.login.bean.ui.MainActivity$JSInterface {
  29. <methods>;
  30. }
  31. #-------------------------------------------------------------------------
  32. #---------------------------------4.反射相关的类和方法-----------------------
  33. #TODO 我的工程里没有。。。
  34. #----------------------------------------------------------------------------
  35. #---------------------------------------------------------------------------------------------------
  36. #-------------------------------------------基本不用动区域--------------------------------------------
  37. #---------------------------------基本指令区----------------------------------
  38. -optimizationpasses 5
  39. -dontusemixedcaseclassnames
  40. -dontskipnonpubliclibraryclasses
  41. -dontskipnonpubliclibraryclassmembers
  42. -dontpreverify
  43. -verbose
  44. -printmapping proguardMapping.txt
  45. -optimizations !code/simplification/cast,!field/*,!class/merging/*
  46. -keepattributes *Annotation*,InnerClasses
  47. -keepattributes Signature
  48. -keepattributes SourceFile,LineNumberTable
  49. #----------------------------------------------------------------------------
  50. #---------------------------------默认保留区---------------------------------
  51. -keep public class * extends android.app.Activity
  52. -keep public class * extends android.app.Application
  53. -keep public class * extends android.app.Service
  54. -keep public class * extends android.content.BroadcastReceiver
  55. -keep public class * extends android.content.ContentProvider
  56. -keep public class * extends android.app.backup.BackupAgentHelper
  57. -keep public class * extends android.preference.Preference
  58. -keep public class * extends android.view.View
  59. -keep public class com.android.vending.licensing.ILicensingService
  60. -keep class android.support.** {*;}
  61. -keepclasseswithmembernames class * {
  62. native <methods>;
  63. }
  64. -keepclassmembers class * extends android.app.Activity{
  65. public void *(android.view.View);
  66. }
  67. -keepclassmembers enum * {
  68. public static **[] values();
  69. public static ** valueOf(java.lang.String);
  70. }
  71. -keep public class * extends android.view.View{
  72. *** get*();
  73. void set*(***);
  74. public <init>(android.content.Context);
  75. public <init>(android.content.Context, android.util.AttributeSet);
  76. public <init>(android.content.Context, android.util.AttributeSet, int);
  77. }
  78. -keepclasseswithmembers class * {
  79. public <init>(android.content.Context, android.util.AttributeSet);
  80. public <init>(android.content.Context, android.util.AttributeSet, int);
  81. }
  82. -keep class * implements android.os.Parcelable {
  83. public static final android.os.Parcelable$Creator *;
  84. }
  85. -keepclassmembers class * implements java.io.Serializable {
  86. static final long serialVersionUID;
  87. private static final java.io.ObjectStreamField[] serialPersistentFields;
  88. private void writeObject(java.io.ObjectOutputStream);
  89. private void readObject(java.io.ObjectInputStream);
  90. java.lang.Object writeReplace();
  91. java.lang.Object readResolve();
  92. }
  93. -keep class **.R$* {
  94. *;
  95. }
  96. -keepclassmembers class * {
  97. void *(**On*Event);
  98. }
  99. #----------------------------------------------------------------------------
  100. #---------------------------------webview------------------------------------
  101. -keepclassmembers class fqcn.of.javascript.interface.for.Webview {
  102. public *;
  103. }
  104. -keepclassmembers class * extends android.webkit.WebViewClient {
  105. public void *(android.webkit.WebView, java.lang.String, android.graphics.Bitmap);
  106. public boolean *(android.webkit.WebView, java.lang.String);
  107. }
  108. -keepclassmembers class * extends android.webkit.WebViewClient {
  109. public void *(android.webkit.WebView, jav.lang.String);
  110. }
  111. #----------------------------------------------------------------------------
  112. #---------------------------------------------------------------------------------------------------

后言

将build.gradle中minifyEnabled设置为true打个包试试吧

  1. release {
  2. minifyEnabled true
  3. proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
  4. }

其他需求可以留言讨论。如果觉得有用请帮忙戳喜欢。。

更新日志

1.模板中的规则有部分与默认的proguard-android.txt文件中的重复了,可以精简一下

  1. #-------------------------------------------定制化区域----------------------------------------------
  2. #---------------------------------1.实体类---------------------------------
  3. #-------------------------------------------------------------------------
  4. #---------------------------------2.第三方包-------------------------------
  5. #-------------------------------------------------------------------------
  6. #---------------------------------3.与js互相调用的类------------------------
  7. #-------------------------------------------------------------------------
  8. #---------------------------------4.反射相关的类和方法-----------------------
  9. #----------------------------------------------------------------------------
  10. #---------------------------------------------------------------------------------------------------
  11. #-------------------------------------------基本不用动区域--------------------------------------------
  12. #---------------------------------基本指令区----------------------------------
  13. -optimizationpasses 5
  14. -dontskipnonpubliclibraryclassmembers
  15. -printmapping proguardMapping.txt
  16. -optimizations !code/simplification/cast,!field/*,!class/merging/*
  17. -keepattributes *Annotation*,InnerClasses
  18. -keepattributes Signature
  19. -keepattributes SourceFile,LineNumberTable
  20. #----------------------------------------------------------------------------
  21. #---------------------------------默认保留区---------------------------------
  22. -keep public class * extends android.app.Activity
  23. -keep public class * extends android.app.Application
  24. -keep public class * extends android.app.Service
  25. -keep public class * extends android.content.BroadcastReceiver
  26. -keep public class * extends android.content.ContentProvider
  27. -keep public class * extends android.app.backup.BackupAgentHelper
  28. -keep public class * extends android.preference.Preference
  29. -keep public class * extends android.view.View
  30. -keep public class com.android.vending.licensing.ILicensingService
  31. -keep class android.support.** {*;}
  32. -keep public class * extends android.view.View{
  33. *** get*();
  34. void set*(***);
  35. public <init>(android.content.Context);
  36. public <init>(android.content.Context, android.util.AttributeSet);
  37. public <init>(android.content.Context, android.util.AttributeSet, int);
  38. }
  39. -keepclasseswithmembers class * {
  40. public <init>(android.content.Context, android.util.AttributeSet);
  41. public <init>(android.content.Context, android.util.AttributeSet, int);
  42. }
  43. -keepclassmembers class * implements java.io.Serializable {
  44. static final long serialVersionUID;
  45. private static final java.io.ObjectStreamField[] serialPersistentFields;
  46. private void writeObject(java.io.ObjectOutputStream);
  47. private void readObject(java.io.ObjectInputStream);
  48. java.lang.Object writeReplace();
  49. java.lang.Object readResolve();
  50. }
  51. -keep class **.R$* {
  52. *;
  53. }
  54. -keepclassmembers class * {
  55. void *(**On*Event);
  56. }
  57. #----------------------------------------------------------------------------
  58. #---------------------------------webview------------------------------------
  59. -keepclassmembers class fqcn.of.javascript.interface.for.Webview {
  60. public *;
  61. }
  62. -keepclassmembers class * extends android.webkit.WebViewClient {
  63. public void *(android.webkit.WebView, java.lang.String, android.graphics.Bitmap);
  64. public boolean *(android.webkit.WebView, java.lang.String);
  65. }
  66. -keepclassmembers class * extends android.webkit.WebViewClient {
  67. public void *(android.webkit.WebView, jav.lang.String);
  68. }
  69. #----------------------------------------------------------------------------
  70. #---------------------------------------------------------------------------------------------------

原文链接:https://www.jianshu.com/p/f3455ecaa56e

发表评论

表情:
评论列表 (有 0 条评论,311人围观)

还没有评论,来说两句吧...

相关阅读

    相关 5分钟!java实现即时通讯

    缓存雪崩 缓存雪崩指的是Redis当中的大量缓存在同一时间全部失效,而假如恰巧这一段时间同时又有大量请求被发起,那么就会造成请求直接访问到数据库,可能会把数据库冲垮。

    相关 5分钟android混淆

    前言 混淆是上线前挺重要的一个环节。android使用的ProGuard,可以起到压缩,混淆,预检,优化的作用。但是很多童鞋还没有掌握正确的写混淆文件的姿势。我希望搞个模