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 反編譯工具,放在這,紀念緬懷它。