1. 程式人生 > >Android 混淆問題排查

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掉了。

掃碼關注公眾號“偉大程式猿的誕生“,更多幹貨等著你~
掃碼關注公眾號“偉大程式猿的誕生“,更多幹貨等著你~
掃碼關注公眾號“偉大程式猿的誕生“,更多幹貨等著你~

在這裡插入圖片描述
公眾號回覆“資料獲取”,獲取更多幹貨哦~
公眾號回覆“資料獲取”,獲取更多幹貨哦~
公眾號回覆“資料獲取”,獲取更多幹貨哦~