Android混淆機制

如何開啓混淆

eclipse

只須要在工程中找到projiect.properties文件,在這個文件中修改下面一段代碼:javascript

proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt複製代碼

Android Studio

在對應的module中,找到build.gradle,在該文件中找到buildTypes,將minifyEnabled置成true,(有對gradle不熟悉的同窗,能夠參考這篇文章Android工程gradle詳解):java

release {//release對應release編譯,debug對應debug編譯

// 是否進行混淆

minifyEnabled true

// 簽名文件

signingConfig signingConfigs.debug

//對應的混淆文件

proguardFiles 'proguard-rules.pro'

}複製代碼

Proguard

Proguard是Android經常使用的免費的混淆工具,若是想了解混淆,須要先對Proguard進行了解android

功能

Proguard主要提供了以下四種功能:json

  • 壓縮:Java源代碼一般被編譯爲字節碼,雖然字節碼比源代碼更加簡潔,但它自己仍包含了不少無用的代碼,Proguard經過分析字節碼,去掉冗餘代碼。
  • 優化: 優化Java字節碼,移除沒有使用到的指令
  • 混淆: 使用無心義的字母對類名方法名,字段名進行重命名,達到混淆的效果
  • 預檢驗: 對上述處理的代碼進行與監獄
    ##基本配置
-dontusemixedcaseclassnames//不使用大小寫形式的混淆名
-dontskipnonpubliclibraryclasses//不跳過library的非public的類
-dontoptimize//不進行優化,優化可能會在某些手機上沒法運行。
-dontpreverify//不淨行預校驗,該校驗是java平臺上的,對android沒啥用處
-keepattributes *Annotation*//對註解中的參數進行保留
-keep public class com.deep.test.MainActivity //對某個class不進行混淆 -dontshrink //不縮減代碼,須要注意,反射調用的代碼會被認爲是無用代碼而刪掉,因此要提早keep出來 -keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}//保持枚舉類中的屬性不被混淆
-keepclassmemberspublic class xxx extends xxx{
void set*(***);
*** get*();
}不混淆任何view子類的get和set方法。
-keepclassmembers class * implements android.os.Parcelable {
public static final android.os.Parcelable$Creator CREATOR;
}//aidl文件不能去混淆
-keep public class com.ebt.app.common.bean.Customer //保留某個類名不被混淆 -keep public class com.ebt.app.common.bean.Customer { *;}
//保留類及其全部成員不被混淆
-keep public class com.ebt.app.common.bean.Customer {
static final;
private void get*();
}//只保留類名及其部分紅員不被混淆
-keep class com.ebt.app.sync.** { *;}
//保留包路徑下全部的類及其屬性和方法
-keepclassmembers class **.R$* {
public static ;
}//資源類變量須要保留複製代碼

下面會對上面提到過的關鍵字進行介紹:android-studio

  • keep:包留類和類中的成員,防止他們被混淆
  • keepnames:保留類和類中的成員防止被混淆,但成員若是沒有被引用將被刪除
  • keepclassmembers:只保留類中的成員,防止被混淆和移除。
  • keepclassmembernames:只保留類中的成員,但若是成員沒有被引用將被刪除。
  • keepclasseswithmembers:若是當前類中包含指定的方法,則保留類和類成員,不然將被混淆。
  • keepclasseswithmembernames:若是當前類中包含指定的方法,則保留類和類成員,若是類成員沒有被引用,則會被移除。
  • -dontwarn:忽視警告。
  • -optimizationpasses 5:proguard對你的代碼進行迭代優化的次數,首先要明白optimization 會對代碼進行各類優化,每次優化後的代碼還能夠再次優化,因此就產生了 優化次數的問題,這裏面的 passes 應該翻譯成 ‘次數’
  • -keepattributes Signature:避免混淆泛型。
  • -keepattributes SourceFile,LineNumberTable:拋出異常時保留代碼行號

一些符號的解釋說明

構造方法
全部成員
全部方法
app

因此全部成員不被混淆能夠這麼寫框架

-keepclasseswithmembers class com.ebt.app.common.bean.Customer {

<init>;

<field>;

<methods>;

}複製代碼

你還能夠在 前面加上private 、public、native等來進一步指定不被混淆的內容: eclipse

-keepclasseswithmembers class com.ebt.app.common.bean.Customer {

public  <init>;

public  <field>;

public  <methods>;

}複製代碼

還能夠再加一些限制(以JSONObject類型做爲參數的構造方法不進行混淆):工具

-keepclasseswithmembers class com.ebt.app.common.bean.Customer {

public  <init>(org.json.JSONObject);
}複製代碼

防止jni的方法被混淆gradle

-keepclasseswithmembernames class * { # 保持native方法不被混淆    
    native <methods>;
}複製代碼
  • $若是咱們要保留一個類中的內部類不被混淆則須要用$符號
  • ? 匹配單一的字符

  • *匹配一段字符

  • %匹配基本類型

  • -libraryjars libs/aaa.jar 不混淆某個jar
    ##注意事項

  • 反射用到的類不混淆(不然反射可能出現問題);
  • AndroidMainfest中的類不混淆,因此四大組件和Application的子類和Framework層下全部的類默認不會進行混淆。自定義的View默認也不會被混淆;因此像網上貼的不少排除自定義View,或四大組件被混淆的規則在Android Studio中是無需加入的;
  • 與服務端交互時,使用GSON、fastjson等框架解析服務端數據時,所寫的JSON對象類不混淆,不然沒法將JSON解析成對應的對象;
  • 使用第三方開源庫或者引用其餘第三方的SDK包時,若是有特別要求,也須要在混淆文件中加入對應的混淆規則;
  • 有用到WebView的JS調用也須要保證寫的接口方法不混淆;
  • Parcelable的子類和Creator靜態成員變量不混淆,不然會產生Android.os.BadParcelableException異常
-keep class * implements Android.os.Parcelable { // 保持Parcelable不被混淆 
    public static final Android.os.Parcelable$Creator *;
}複製代碼
  • 使用enum類型時須要注意避免如下兩個方法混淆,由於enum類的特殊性,如下兩個方法會被反射調用,見第二條規則。
-keepclassmembers enum * {  
    public static **[] values();  
    public static ** valueOf(java.lang.String);  
}複製代碼
相關文章
相關標籤/搜索