Android 混淆-詳細(xì)解讀

目錄.png

ProGuard是一個(gè)免費(fèi)的Java類文件縮小,優(yōu)化,混淆和預(yù)驗(yàn)證的工具。它檢測(cè)和刪除未使用的類,字段,方法和屬性;優(yōu)化字節(jié)碼并刪除未使用的指令;它使用短的無意義的名稱重命名剩余的類,字段和方法。所得到的應(yīng)用程序和庫更小,更快,并且更好地針對(duì)逆向工程進(jìn)行優(yōu)化。

一、混淆的四個(gè)功能

  1. 壓縮:移除無效的類、屬性、方法等;
  2. 優(yōu)化:優(yōu)化字節(jié)碼,并刪除未使用的結(jié)構(gòu);
  3. 混淆:類名、屬性名、方法名混淆成難度字母;
  4. 預(yù)效驗(yàn)

minifyEnabled改為true

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

二、不能參與混淆的

  1. AndroidManifest中配置的類,比如四大組件和Application類。
  2. Fragment不參與混淆app包下和v4包下的分別keep下
  3. 所有實(shí)現(xiàn)了Serializable接口的類成員
  4. JNI調(diào)用的方法
  5. 反射用到的類
  6. 枚舉
  7. 項(xiàng)目中暴露的JS接口類及其調(diào)用的方法的聲明也不能混淆;
  8. Layout文件引用到的自定義View
  9. 注解的類或參數(shù)或函數(shù)不能參與混淆
  10. 一些引入的第三方庫(一般都會(huì)有混淆說明的)

三、AAR對(duì)外提供的接口的處理

把a(bǔ)ar對(duì)外提供的接口,統(tǒng)一到一個(gè)類中,在混淆文件中加上keep方法,讓這個(gè)類不被混淆,同時(shí)R文件也能混淆
例如

-dontwarn okhttp3.**
-keep class okhttp3.**{*;}

四、混淆的文件示例

以下代碼的因包名而變化

#混淆的初始化配置##############################################
-ignorewarnings                     # 忽略警告,避免打包時(shí)某些警告出現(xiàn)
-optimizationpasses 5               # 指定代碼的壓縮級(jí)別
-dontusemixedcaseclassnames         # 是否使用大小寫混合
-dontskipnonpubliclibraryclasses    # 是否混淆第三方j(luò)ar
-dontpreverify                      # 混淆時(shí)是否做預(yù)校驗(yàn)
-verbose                            # 混淆時(shí)是否記錄日志
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*    # 混淆時(shí)所采用的算法

####################################################################################################
## 1.四大組件和Application類不參與混淆
-keep public class * extends android.app.Activity
-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.Application

## 2.Fragment不需要在AndroidManifest.xml中注冊(cè),需要額外保護(hù)下
-keep public class * extends android.support.v4.app.Fragment
-keep public class * extends android.app.Fragment
-keep public class * extends android.support.v4.app.FragmentActivity

## 3.保持所有實(shí)現(xiàn) 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();
}

## 6.枚舉不被混淆
-keepclassmembers enum * {
    public static **[] values();
    public static ** valueOf(java.lang.String);
}

## 7.MyJavaInterface不能混淆,其調(diào)用的方法聲明也不能混淆,所以還要添加如下混淆
-keepclassmembers class com.example.administrator.webviewpagescannerapp.other.MJavascriptInterface{  
    public *;  
}
-keepattributes *JavascriptInterface*  
// 注解不參與混淆
-keepattributes *Annotation*

## 8.Layout文件引用到的自定義View
-keep public class * extends android.view.View {
    public <init>(android.content.Context);
    public <init>(android.content.Context, android.util.AttributeSet);
    public <init>(android.content.Context, android.util.AttributeSet, int);
    public void set*(...);
}

##########################實(shí)體類不參與混淆############################
-keep class ai.botbrain.ttcloud.sdk.entity.** { *; }


######################對(duì)外提供的接口類不參與混淆################################
-keep class ai.botbrain.ttcloud.api.** { *; }

####################################################################################################


-dontwarn android.support.**

五、混淆時(shí)候遇到的ERROR

混淆遇到的錯(cuò)誤

Warning: there were 3 instances of library classes depending on program classes.
         You must avoid such dependencies, since the program classes will
         be processed, while the library classes will remain unchanged.
         (http://proguard.sourceforge.net/manual/troubleshooting.html#dependency)

解決

 -ignorewarnings

六、混淆的gradle配置

默認(rèn)情況下,Android Plugin會(huì)自動(dòng)給項(xiàng)目設(shè)置同時(shí)構(gòu)建應(yīng)用的debugrelease版本。兩個(gè)版本之間不同主要圍繞著能否在一個(gè)安全設(shè)備上調(diào)試,以及APK如何簽名。
所以當(dāng)想在debug時(shí)候關(guān)閉混淆功能時(shí),同時(shí)把releasedebug下的minifyEnabled置為false

release {
    // 是否混淆
    minifyEnabled false
    proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
debug {
    minifyEnabled false
    proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}

七、給別人提供混淆的AAR注意事項(xiàng)

需求:把項(xiàng)目中的某一個(gè)模塊,打包成一個(gè)混淆的aar,集成到其他的項(xiàng)目中,同時(shí)暴露的接口不混淆,這個(gè)aar的依賴庫跟其他項(xiàng)目的依賴庫不能沖突。

模塊中引入的jar在以下情況下是混淆不成功的:
1.假設(shè)有兩個(gè)模塊,moduleAmoduleB
moduleA依賴moduleB
moduleB中引入了第三方的jar,混淆的配置是在moduleA中,這種情況下,moduleB中的jar是不被混淆的。

2.引入的jar包是以網(wǎng)絡(luò)庫方式的依賴,是不被混淆的。

知道了以上注意點(diǎn),可以更好的為別人提供混淆后的aar,并減小類的沖突。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 173,287評(píng)論 25 708
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 134,923評(píng)論 18 139
  • 聲明 這篇文章更多的是做一個(gè)整理,內(nèi)容來自于ProGuard官方文檔以及各種博客等,相關(guān)文章的鏈接在參考目錄里,感...
    夷陵小祖閱讀 3,708評(píng)論 0 23
  • 轉(zhuǎn)載注明出處:http://www.lxweimin.com/p/5255b100930e 0. 前言 完全由個(gè)人翻...
    王三的貓阿德閱讀 2,565評(píng)論 0 4
  • 1. 主要為了捋捋我這一個(gè)月都干了啥,沒嘛意思,想看的看,不想看的小伙伴可以默默關(guān)掉啦。 2. 做總結(jié)是受悅醬啟發(fā)...
    于瑞O芝閱讀 258評(píng)論 0 1