混淆 Dart 程式碼
如何從 Dart 二進位制檔案中移除函式和類名稱。
什麼是程式碼混淆?
#程式碼混淆 是修改應用二進位制檔案以使其難以被人理解的過程。混淆會隱藏編譯後的 Dart 程式碼中的函式和類名,用其他符號替換每個符號,從而使攻擊者難以對你的專屬應用進行逆向工程。
侷限性與警告
#Flutter 的程式碼混淆僅適用於 釋出構建 (release build)。
程式碼混淆不會加密資源,也不能防止逆向工程。它只是用更晦澀的名稱重新命名了符號。
Web 應用不支援混淆。Web 應用可以進行壓縮 (minification),這能達到類似的效果。當你構建 Flutter Web 應用的釋出版本時,Web 編譯器會自動壓縮應用。欲瞭解更多資訊,請參閱 構建併發布 Web 應用。
支援的目標平臺
#以下構建目標支援本頁面介紹的混淆過程:
aarapkappbundleiosios-frameworkipalinuxmacosmacos-frameworkwindows
有關特定構建目標可用命令列選項的詳細資訊,請執行以下命令。輸出中應列出 --obfuscate 和 --split-debug-info 選項。如果沒有顯示,你需要安裝較新版本的 Flutter 才能混淆程式碼。
flutter build <build-target> -h
-
<build-target>:構建目標。例如apk。
混淆你的應用
#要混淆應用並建立符號對映表,請在釋出模式下使用 flutter build 命令,並帶上 --obfuscate 和 --split-debug-info 選項。如果你將來需要除錯混淆後的應用,則必須保留該符號對映表。
-
執行以下命令以混淆你的應用並生成符號 (SYMBOLS) 檔案:
flutter build <build-target> \ --obfuscate \ --split-debug-info=/<symbols-directory>-
<build-target>:構建目標。例如apk。 -
<symbols-directory>:存放符號檔案的目錄。例如out/android。
-
-
一旦混淆了二進位制檔案,請備份符號檔案。如果你丟失了原始的符號檔案,又想對堆疊跟蹤進行反混淆,你將會需要它。
解讀混淆後的堆疊跟蹤
#要除錯由混淆後的應用生成的堆疊跟蹤,請按照以下步驟將其轉換為可讀格式:
-
找到匹配的符號檔案。例如,來自 Android arm64 裝置的崩潰日誌需要使用
app.android-arm64.symbols。 -
將堆疊跟蹤檔案(儲存在檔案中)和符號檔案一同提供給
flutter symbolize命令。flutter symbolize \ -i <stack-trace-file> \ -d <obfuscated-symbols-file>-
<stack-trace-file>:堆疊跟蹤的檔案路徑。例如???。 -
<obfuscated-symbols-file>:包含混淆符號的符號檔案路徑。例如out/android/app.android-arm64.symbols。
有關
symbolize命令的更多資訊,請執行flutter symbolize -h。 -
解讀混淆後的名稱
#你可以生成一個包含混淆對映的 JSON 檔案。混淆對映是一個 JSON 陣列,其中包含原始名稱與混淆名稱的配對。例如 ["MaterialApp", "ex", "Scaffold", "ey"],其中 ex 是 MaterialApp 的混淆名稱。
要生成混淆對映,請使用以下命令:
flutter build <build-target> \
--obfuscate \
--split-debug-info=/<symbols-directory> \
--extra-gen-snapshot-options=--save-obfuscation-map=/<obfuscation-map-file>
-
<build-target>:構建目標。例如apk。 -
<symbols-directory>:存放符號的目錄。例如out/android -
<obfuscation-map-file>:應放置 JSON 混淆對映的檔案路徑。例如out/android/map.json
注意事項
#在編寫最終會成為混淆二進位制檔案的應用時,請注意以下事項:
-
依賴匹配特定類名、函式名或庫名的程式碼將會失敗。例如,以下對
expect()的呼叫在混淆後的二進位制檔案中將無法工作:dartexpect(foo.runtimeType.toString(), equals('Foo')); 列舉 (Enum) 名稱目前不會被混淆。