[轉]Android ProGuard 混淆 詳解

Android ProGuard 混淆 詳解

標籤: Android混淆
27240人閱讀 評論(5) 收藏 舉報
分類:
如今寫的app 基本都是通過混淆了的,若是不混淆, 發佈出去,別人一反編譯 就能夠直接看你的源碼了
ok 來講一下混淆吧:

我如今用的AndroidStudio , 只須要在 build.grade 的配置文件中配置以下便可: html

 

  1. buildTypes {  
  2.     debug {  
  3.         versionNameSuffix ".dev"  
  4.     }  
  5.   
  6.     release {  
  7.         debuggable false  
  8.         minifyEnabled true  
  9.         proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'  
  10.         signingConfig signingConfigs.release  
  11.     }  
  12. }  
buildTypes {
    debug {
        versionNameSuffix ".dev"
    }

    release {
        debuggable false
        minifyEnabled true
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        signingConfig signingConfigs.release
    }
}

 

 

proguardFiles getDefaultProguardFile 就是制定 混淆規則的文件, AndroidStudio默認生成了proguard-rules.pro 文件 
 

 


 

混淆 ProGuard經常使用語法
 
  1. -libraryjars class_path 應用的依賴包,如android-support-v4  
  2. -keep [,modifier,...] class_specification 不混淆某些類  
  3. -keepclassmembers [,modifier,...] class_specification 不混淆類的成員  
  4. -keepclasseswithmembers [,modifier,...] class_specification 不混淆類及其成員  
  5. -keepnames class_specification 不混淆類及其成員名  
  6. -keepclassmembernames class_specification 不混淆類的成員名  
  7. -keepclasseswithmembernames class_specification 不混淆類及其成員名  
  8. -assumenosideeffects class_specification 假設調用不產生任何影響,在proguard代碼優化時會將該調用remove掉。如system.out.println和Log.v等等  
  9. -dontwarn [class_filter] 不提示warnning  
-libraryjars class_path 應用的依賴包,如android-support-v4
-keep [,modifier,...] class_specification 不混淆某些類
-keepclassmembers [,modifier,...] class_specification 不混淆類的成員
-keepclasseswithmembers [,modifier,...] class_specification 不混淆類及其成員
-keepnames class_specification 不混淆類及其成員名
-keepclassmembernames class_specification 不混淆類的成員名
-keepclasseswithmembernames class_specification 不混淆類及其成員名
-assumenosideeffects class_specification 假設調用不產生任何影響,在proguard代碼優化時會將該調用remove掉。如system.out.println和Log.v等等
-dontwarn [class_filter] 不提示warnning

Android 混淆原則:

 

 

反射用到的類不混淆
JNI方法不混淆
AndroidMainfest中的類不混淆,四大組件和Application的子類和Framework層下全部的類默認不會進行混淆
Parcelable的子類和Creator靜態成員變量不混淆,不然會產生android.os.BadParcelableException異常
使用GSON、fastjson等框架時,所寫的JSON對象類不混淆,不然沒法將JSON解析成對應的對象
使用第三方開源庫或者引用其餘第三方的SDK包時,須要在混淆文件中加入對應的混淆規則
有用到WEBView的JS調用也須要保證寫的接口方法不混淆

先看看google默認混淆文件: \sdk\tools\proguard\proguard-android.txt 
  1. -keepattributes *Annotation*//使用註解須要添加  
  2. -keep public class com.google.vending.licensing.ILicensingService  
  3. -keep public class com.android.vending.licensing.ILicensingService  
  4.   
  5. # For native methods, see http://proguard.sourceforge.net/manual/examples.html#native  
  6. -keepclasseswithmembernames class * {//指定不混淆全部的JNI方法  
  7.     native <methods>;  
  8. }  
  9.   
  10. # keep setters in Views so that animations can still work.  
  11. # see http://proguard.sourceforge.net/manual/examples.html#beans  
  12. -keepclassmembers public class * extends android.view.View {//全部View的子類及其子類的get、set方法都不進行混淆  
  13.    void set*(***);  
  14.    *** get*();  
  15. }  
  16.   
  17. # We want to keep methods in Activity that could be used in the XML attribute onClick  
  18. -keepclassmembers class * extends android.app.Activity {//不混淆Activity中參數類型爲View的全部方法  
  19.    public void *(android.view.View);  
  20. }  
  21.   
  22. # For enumeration classes, see http://proguard.sourceforge.net/manual/examples.html#enumerations  
  23. -keepclassmembers enum * {//不混淆Enum類型的指定方法  
  24.     public static **[] values();  
  25.     public static ** valueOf(java.lang.String);  
  26. }  
  27. //不混淆Parcelable和它的子類,還有Creator成員變量  
  28. -keep class * implements android.os.Parcelable {  
  29.   public static final android.os.Parcelable$Creator *;  
  30. }  
  31. //不混淆R類裏及其全部內部static類中的全部static變量字段  
  32. -keepclassmembers class **.R$* {  
  33.     public static <fields>;  
  34. }  
  35.   
  36. # The support library contains references to newer platform versions.  
  37. # Don't warn about those in case this app is linking against an older  
  38. # platform version.  We know about them, and they are safe.  
  39. -dontwarn android.support.**//不提示兼容庫的錯誤警告  
-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
-keepclasseswithmembernames class * {//指定不混淆全部的JNI方法
    native <methods>;
}

# keep setters in Views so that animations can still work.
# see http://proguard.sourceforge.net/manual/examples.html#beans
-keepclassmembers public class * extends android.view.View {//全部View的子類及其子類的get、set方法都不進行混淆
   void set*(***);
   *** get*();
}

# We want to keep methods in Activity that could be used in the XML attribute onClick
-keepclassmembers class * extends android.app.Activity {//不混淆Activity中參數類型爲View的全部方法
   public void *(android.view.View);
}

# For enumeration classes, see http://proguard.sourceforge.net/manual/examples.html#enumerations
-keepclassmembers enum * {//不混淆Enum類型的指定方法
    public static **[] values();
    public static ** valueOf(java.lang.String);
}
//不混淆Parcelable和它的子類,還有Creator成員變量
-keep class * implements android.os.Parcelable {
  public static final android.os.Parcelable$Creator *;
}
//不混淆R類裏及其全部內部static類中的全部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.**//不提示兼容庫的錯誤警告

 


若是加入一些本身的混淆規則 只須要在 proguard-rules.pro 中文件加入本身的混淆規則便可,
其實google以及給我提供很好的打包規則, 即proguard-rules.pro 啥也不寫, 我打出來的release包也是混淆好的
可是咱們會遇到一些狀況, 不得不 添加本身的混淆規則:
1. 代碼中使用了反射,如一些ORM框架的使用 
          須要保證類名 方法不變, 否則混淆後, 就反射不了
2. 使用GSON、fastjson等JSON解析框架所生成的對象類
          生成的bean實體對象,內部大可能是經過反射來生成, 不能混淆
3. 引用了第三方開源框架或繼承第三方SDK,如開源的okhttp網絡訪問框架,百度定位SDK等
          在這些第三庫的文檔中 一班會給出 相應的 混淆規則, 複製過來便可
4. 有用到WEBView的JS調用接口
          沒真麼用過這塊, 不是很熟, 網上那個看到的
5. 繼承了Serializable接口的類
          在反序列畫的時候, 須要正確的類名等, 在Android 中大可能是實現 Parcelable來序列化的

ok 其實本身加入的規則 通常都是說,某某類 不混淆等等

若是用到了反射須要加入 : 
  1. -keepattributes Signature  
  2. -keepattributes EnclosingMethod  
-keepattributes Signature
-keepattributes EnclosingMethod

若是想讓一些bean 對象不混淆, 裏 com.czy.bean 包下面的全是 Json框架生成的bean對象, 那麼只需加入:
  1. -keep class czy.**{*;}//不混淆全部的com.czy.bean包下的類和這些類的全部成員變量  
-keep class czy.**{*;}//不混淆全部的com.czy.bean包下的類和這些類的全部成員變量
繼承了Serializable接口的類,須要加上:

 

  1. //不混淆Serializable接口的子類中指定的某些成員變量和方法  
  2. -keepclassmembers class * implements java.io.Serializable {  
  3.     static final long serialVersionUID;  
  4.     private static final java.io.ObjectStreamField[] serialPersistentFields;  
  5.     private void writeObject(java.io.ObjectOutputStream);  
  6.     private void readObject(java.io.ObjectInputStream);  
  7.     java.lang.Object writeReplace();  
  8.     java.lang.Object readResolve();  
  9. }  
//不混淆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();
}

關於第三方的庫的, 一班都是看他們的官方文檔

有用到WEBView的JS調用接口,需加入以下規則: 
  1. -keepclassmembers class fqcn.of.javascript.interface.for.webview {  
  2.    public *;  
  3. }  
  4. -keep class com.xxx.xxx.** { *; }//保持WEB接口不被混淆 此處xxx.xxx是本身接口的包名  
-keepclassmembers class fqcn.of.javascript.interface.for.webview {
   public *;
}
-keep class com.xxx.xxx.** { *; }//保持WEB接口不被混淆 此處xxx.xxx是本身接口的包名

不混淆某個類:

 

 

  1. -keep class com.czy.**//不混淆全部com.czy包下的類,** 換成具體的類名則表示不混淆某個具體的類  
-keep class com.czy.**//不混淆全部com.czy包下的類,** 換成具體的類名則表示不混淆某個具體的類
不混淆某個類和成員變量:

 

 

  1. -keep class com.clock.**{*;}//不混淆全部com.clock包下的類和類中的全部成員變量,**能夠換成具體類名,*能夠換成具體的字段,可參照Serialzable的混淆  
-keep class com.clock.**{*;}//不混淆全部com.clock包下的類和類中的全部成員變量,**能夠換成具體類名,*能夠換成具體的字段,可參照Serialzable的混淆

 

移除一些log代碼:
移除Log類打印各個等級日誌的代碼,打正式包的時候能夠作爲禁log使用,這裏能夠做爲禁止log打印的功能使用,另外的一種實現方案是經過BuildConfig.DEBUG的變量來控制 
  1. -assumenosideeffects class android.util.Log {  
  2.     public static *** v(...);  
  3.     public static *** i(...);  
  4.     public static *** d(...);  
  5.     public static *** w(...);  
  6.     public static *** e(...);  
  7. }  
-assumenosideeffects class android.util.Log {
    public static *** v(...);
    public static *** i(...);
    public static *** d(...);
    public static *** w(...);
    public static *** e(...);
}

上面這些內容大多都是看的別人的, 本身記錄下會更有印象:
參考了一下內容:

官方文檔:
 




 




 

 

 

9
0
 
 
 

 

相關文章
相關標籤/搜索