[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>;
}