[Android] Deobfuscate StackTrace
在使用 Android Proguard 的時候,可以先看看 Google 工程師是為什麼要設計 Proguard 的功能與他們想要解決的問題是什麼?然後本篇想要記錄一些在開發 Android 手機程式的時候處理如何處理 Obfuscate / Deobfuscat ?
使用 Proguard GUI 反轉 StackTrace
想要反解碼 Google Play Console 上面顯示的 StackTrace 訊息,可以使用產生的 mapping.txt 配合 Android SDK 裡面已經有的程式去解碼,啟動 proguard GUI 的方法可以使用以下的指令:
cd /Library/Android/sdk/tools/proguard/bin
sh proguardgui.sh
啟動 GUI 之後在 Obfuscated stack trace 處填上從 Google Play Console 找到的 Stack Trace,
java.lang.NullPointerException:
at kuma.LingoCards.LanguageActivity.a (LanguageActivity.java:46)
at kuma.LingoCards.LanguageActivity.Play_single (LanguageActivity.java:104)
at kuma.LingoCards.LanguageActivity$6.handleMessage (LanguageActivity.java:214)
at android.os.Handler.dispatchMessage (Handler.java:108)
at android.os.Looper.loop (Looper.java:166)
at android.app.ActivityThread.main (ActivityThread.java:7529)
at java.lang.reflect.Method.invoke (Method.java)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run (Zygote.java:245)
at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:921)
另外在 Mapping file 的欄位選擇 apk 產生時產生的 mapping.txt,原本的 StackTrace 裡面我們只知道在 LanguageActivity.Play_single 裡面的 a 發生 NullPointerException,但是經過 De-obfuscated stack trace 之後,我們還是只能知道有可能是 getFileDescriptor, loadSetLanguageItems 或是 sendIntentToPlayActivity 發生錯誤?ㄗ資訊還是不太夠!
參考
proguard-rules.pro 要怎麼寫?參考網站我們列出以下比較常用到混淆設定的指令,詳細所有 proguard-rules.pro 可以用到的選項可以在官網查詢:
(表示混淆時不使用大小寫混合類名)
-dontusemixedcaseclassnames
(表示不跳過library中的非public的類)
-dontskipnonpubliclibraryclasses
(表示打印混淆的詳細信息)
-verbose
(表示不進行優化)
-dontoptimize
(表示不進行預校驗)
-dontpreverify
(表示對註解中的參數進行保留)
-keepattributes *Annotation*
(表示不混淆繼承 Android.app.Activity 的類別)
-keep public class * extends Android.app.Activity
(表示不混淆Activity中參數是View的方法)
-keepclassmembers class * extends android.app.Activity {
public void *(android.view.View);
}
(不混淆所有有 butterknife Annotation 的類別)
-keepclasseswithmembernames class * {
@butterknife.* <fields>;
}