ProGuard 程式碼混淆保護


ProGuard 主要功能,可以壓縮程式去除用不到的資源,優化和混淆程式碼。
(shrinks, optimizes, obfuscates)
ProGuard 工具目前已在 Android SDK 中(Android/sdk/tools/proguard),可以透過 Gradle 設定編譯發行APP應用程式。

ProGuard 處理程式碼流程:

  • Shrink(壓縮)
    ProGuard 會遞歸地確定哪些類別和類別成員被使用,沒用到則會被丟棄移除。
  • Optimize(優化)
    ProGuard 會進一步分析和優化方法。比如一些無用的參數會被丟棄,一些方法會做內聯。
  • Obfuscate(混淆)
    這個過程就是進行重命名了,把原來包含註釋意義的類別名、方法名等進行無意義重新命名為,如:a,b,c,d,e,f…等。
  • Preverify(預校驗)
    這個步驟是將預校驗信息添加到類中。
混淆程式碼,只是增加反編譯窺看原始碼難度,但有心人士,還是有可能破譯。
ProGuard 為 GuardSquare 公司開源工具,該公司另外一套 DexGuard 為進階混淆工具須額外購買付費,且價格相當高昂,不便宜。
在開發中的程式 buildTypes 為 debug 模式,一般情況下不會開啟 Proguard。 release 模式為正式對外發佈版本,才會開啟。

Gradle 混淆開啟方法

android {
    buildTypes {
        debug {
            minifyEnabled false //關閉,混淆
            shrinkResources false //關閉,去除用到的資源
            proguardFiles getDefaultProguardFile('proguard-android.txt'),
                    'proguard-rules.pro'
        }
        release {
            minifyEnabled true //開啟,混淆
            shrinkResources true //開啟,去除用到的資源
            proguardFiles getDefaultProguardFile('proguard-android.txt'),
                    'proguard-rules.pro'
        }
    }
}
其中 proguard-android.txt 為預設的混淆規則,該文件在SDK目錄 /tools/proguard 中。 proguard-rules.pro 為自定義的混淆規則。
每次建置完時 ProGuard 都會輸出下列文件:
  • dump.txt
    說明APK 中所有類文件的內部結構。
  • mapping.txt
    提供原始與混淆過的類、方法和字段名稱之間的轉換。
  • seeds.txt
    列出未進行混淆的類和成員。
  • usage.txt
    列出從APK 移除的代碼。
這些文件保都會存在/build/outputs/mapping/release/中。
使用 Proguard 時,不是只要 minifyEnabled 設為 true,就大公告成,因為 ProGuard 預設配置文件 (proguard-android.txt) ,會移除所有未使用的代碼。大部分情況下也會移除到真正需要的程式碼。這時我們就需要自定義哪些程式碼,需要特地保留,不要移除、不要混淆。

基本常用混淆語法

  • 關鍵字 keep 就是要去保留什麼,不要去混淆什麼
  • #為註解

保留類別和類別成員

保留防止被刪除或重命名防止被重命名
類別和類別成員-keep-keepnames
僅類別成員-keepclassmembers-keepclassmembernames
如果擁有某成員,保留類別和類別成員-keepclasseswithmembers-keepclasseswithmembernames

類別成員中的符號

符號作用
匹配所有構造器
匹配所有欄位
匹配所有方法
*匹配所有欄位和方法

常用符號

符號作用
*匹配任意長度字符,但不含包名分隔符(.)
**匹配任意長度字符,並且包含包名分隔符(.)
***匹配任意參數類型
匹配任意長度的任意類型參數
%匹配任何原始類型
?匹配類名中的任何單個字符

常用 ProGuard 模板

#壓縮比,預設5不修改
-optimizationpasses 5 

#不使用大小寫混合,混淆後類名稱為小寫
-dontusemixedcaseclassnames 

#指定不去忽略公開的 publicli classes
-dontskipnonpubliclibraryclasses

#混淆後產生印射文件
-verbose 

#註解此行,可以自動上傳 mapping 檔到 Firebase
#-printmapping mapping.txt

#保留泛型
-keepattributes Signature

# 不做預校驗,加速建置速度
-dontpreverify

# 保留Annotation不混淆
-keepattributes *Annotation*,InnerClasses
 
# 避免混淆泛型
-keepattributes Signature
 
# 抛出異常時保留檔名與行數
-keepattributes SourceFile,LineNumberTable

# 保留 android-support
-dontwarn android.support.design.**
-keep class android.support.design.** { *; }
-keep interface android.support.design.** { *; }
-keep public class android.support.design.R$* { *; }

移除 Log 模板 ,正式版不要印出除錯訊息

-assumenosideeffects class android.util.Log {
    public static boolean isLoggable(java.lang.String, int);
    public static *** i(...);
    public static *** w(...);
    public static *** e(...);
    public static *** d(...);
    public static *** v(...);
}

ProGuard GUI 圖形化介面

檔案位置:Android/sdk/tools/proguard/bin/proguardgui.sh
當時建置完成的產出的 mapping.txt檔案,搭配 ReTrace,即可將混淆過的程式碼,解析回原本程式名稱。

反編譯工具

  • 驗證,自己的程式碼是否混淆成功
  • 哈,研究探訪其他APP 樂園 秘境

JADX

當今反編譯 Android APP APK,霸主,如果有其他更好用的,歡迎下方留言,一起交流~ 交流~

Android Developer - Analyze your build with APK Analyzer

內建在 Android Studio 的小工具,可以快速查看哪張圖太胖,需要瘦身

Java Decompiler

已過時,曾經最著名輝煌的 Java 反編譯工具,放在這,紀念緬懷它。

ProGuard 說明文件

從零開始學 Kotlin 程式設計: 線上教學課程目錄
Android , Kotlin , 開發 , 教學 , 範例 , 入門 , 基礎 , 新手 , 程式設計 , 課程

這個網誌中的熱門文章

2023 最新入門零基礎 Kotlin教學【從零開始學 Kotlin 程式設計】Kotlin 教學課程目錄 (Android Kotlin, IntelliJ IDEA, Android Studio, Android APP 開發教學)

nano 文字編輯器

2022 最新入門零基礎 Flutter教學 【Flutter 程式設計入門實戰 30 天】Flutter 教學課程目錄 (IntelliJ IDEA 開發教學)

16天記下7000單字

最新入門零基礎 Java 教學【從零開始學 Java 程式設計】Java教學課程目錄 (IntelliJ IDEA 開發教學)