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 , 開發 , 教學 , 範例 , 入門 , 基礎 , 新手 , 程式設計 , 課程

留言

這個網誌中的熱門文章

16天記下7000單字