Android 混淆問題排查
問題
近期在開發過程中,突然出現混淆後程序出現執行時異常,編譯是正常的,不混淆也是正常的,
錯誤資訊如下提示
12-07 14:10:27.056 10603-10603/? E/AndroidRuntime: FATAL EXCEPTION: main java.lang.RuntimeException: Unable to instantiate application com.xzxj.frame.base.BaseApplication: java.lang.ClassCastException: com.xzxj.frame.base.BaseApplication cannot be cast to android.app.Application at android.app.LoadedApk.makeApplication(LoadedApk.java:587) at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4891) at android.app.ActivityThread.-wrap1(ActivityThread.java) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1530) at android.os.Handler.dispatchMessage(Handler.java:111) at android.os.Looper.loop(Looper.java:207) at android.app.ActivityThread.main(ActivityThread.java:5692) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:888) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:749) Caused by: java.lang.ClassCastException: com.xzxj.frame.base.BaseApplication cannot be cast to android.app.Application at android.app.Instrumentation.newApplication(Instrumentation.java:1001) at android.app.Instrumentation.newApplication(Instrumentation.java:986) at android.app.LoadedApk.makeApplication(LoadedApk.java:582) at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4891) at android.app.ActivityThread.-wrap1(ActivityThread.java) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1530) at android.os.Handler.dispatchMessage(Handler.java:111) at android.os.Looper.loop(Looper.java:207) at android.app.ActivityThread.main(ActivityThread.java:5692) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:888) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:749)
思路
1、通過上面的錯誤資訊首先會去排查
AndroidManifest.xml
檔案是否註冊了Appliction,發現都是註冊好的。2、考慮到關閉混淆正常,開啟混淆異常,那麼就定位到時混淆的問題
3、既然是混淆問題那就檢視混淆配置檔案
proguard-rules.pro
,基本的配置都已經防混淆了4、接下來的思路就是通過反編譯來檢視
BaseApplication
到底出了啥額問題
過程
第一步
我們看到下面反編譯的程式碼
我們的BaseApplication
繼承的application被混淆了
那麼在’proguard-rules.pro
-keep class android.app.**{*;}
執行後報錯如下:
12-10 15:16:07.442 15939-15939/? E/AndroidRuntime: FATAL EXCEPTION: main java.lang.VerifyError: Rejecting class com.xzxj.frame.base.BaseApplication because it failed compile-time verification (declaration of 'com.xzxj.frame.base.BaseApplication' appears in /data/app/com.xzxj-1/base.apk:classes2.dex) at java.lang.Class.newInstance(Native Method) at android.app.Instrumentation.newApplication(Instrumentation.java:1001) at android.app.Instrumentation.newApplication(Instrumentation.java:986) at android.app.LoadedApk.makeApplication(LoadedApk.java:582) at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4891) at android.app.ActivityThread.-wrap1(ActivityThread.java) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1530) at android.os.Handler.dispatchMessage(Handler.java:111) at android.os.Looper.loop(Looper.java:207) at android.app.ActivityThread.main(ActivityThread.java:5692) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:888) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:749)
看到錯誤資訊變化了,心裡應該開心,看來離解決問題更近一步了。
第二步
我們繼續反編譯,看到繼承的介面還是有問題的,雖然感覺不是這個引起的但是強迫症,把介面防混淆,加入如下程式碼:
-keep interface com.xzxj.frame.** { *; }
第三步
執行後依然是同樣的錯誤資訊,反編譯後代碼如下:
此時對比程式碼分析,應該是如下問題造成的,
混淆前:
public static Context getBaseApplication() {
return instance;
}
混淆後:
public static j a()
{
return b;
}
看來Context
也被混淆了,接下來在’proguard-rules.pro’中加入一句-keep class android.content.**{*;}
第四步:
接下來就是見證奇蹟的時刻,果然執行正常,我們看一下混淆後的程式碼
結論
綜上,我們可以分析出來是我們的android
包下面的檔案都被混淆了,於是我們把-keep class android.content.**{*;}
和-keep class android.app.**{*;}
合二為一-keep class android.**{*;}
不過按照道理來講這個不應該被混淆,系統會做處理,猜測可能是某個配置導致系統的一些配置失效,至於該工程為啥這麼奇葩待後續分析。
所以以後遇到混淆的問題就按照提示一步一步排查,一定要反編譯檔案來分析問題,不然無法定位原因。
還有第一次混淆後建議反編譯檢視一下包裡面的程式碼,有沒有需要混淆的核心程式碼被keep掉了。
掃碼關注公眾號“偉大程式猿的誕生“,更多幹貨等著你~
掃碼關注公眾號“偉大程式猿的誕生“,更多幹貨等著你~
掃碼關注公眾號“偉大程式猿的誕生“,更多幹貨等著你~
公眾號回覆“資料獲取”,獲取更多幹貨哦~
公眾號回覆“資料獲取”,獲取更多幹貨哦~
公眾號回覆“資料獲取”,獲取更多幹貨哦~