1. 程式人生 > >Android odex檔案反編譯

Android odex檔案反編譯

odex 是經過優化的dex檔案,且獨立存在於apk檔案。odex 多用於系統預製應用或服務。通過將apk中的dex檔案進行 odex,可以載入 apk 的啟動速度,同時減小空間的佔用。請參考ODEX關於 odex 的說明。

在反編譯 odex 檔案的過程中,我們需要使用到以下工具

smali/baksmali是odex與dex檔案格式互相轉換的兩個工具,dex2jar則是將dex檔案轉為java的jar檔案,JD Compiler用於反編譯jar檔案。也就是說,經過以上一系列的操作,我們最終可以從一個odex檔案得到一個可讀的java檔案。(事實上,也不是完全可讀,與原始碼上還是有差別,有時候部分程式碼還無法反編譯過來,只能以jdk虛擬機器指令的方式存在了)。

首先,一個 odex 檔案的生成過程是:java -> class -> dex -> odex,那麼反編譯的就是上面過程的逆操作了:odex -> dex -> class -> java。

我的測試環境:

  • Android 4.1.2
  • Samsung Galaxy II

以Android系統中的 uiautomator.odex 檔案為例,目標是反編譯其原始碼(其實它的原始碼grepcode).

工具準備

建立一個臨時目錄test,將 smali/baksmali 相關的工具都放入其中。

反編譯 (odex -> dex)

首先,將目標 odex 檔案拿出來。

1 2 cd test adb pull /system/framework/uiautomator.odex

在合成 odex 檔案過程中,還需要用到很多依賴檔案,它們同樣也是 odex 格式的。因此在合成時,我們需要根據情況反覆從手機中抽取相關的依賴包。

關於命令的使用,直接執行 java -jar baksmali-2.0.2.jar 可以得到相關的使用說明。這裡要用到的引數主要是:

  • [-a | --api-level]: Android API等級,Android 4.1.2是16
  • [-x | --deodex]: 操作,反編譯
  • [-d|--bootclasspath-dir]
    : 依賴包的目錄,我們用當前目錄.

開始反編譯,執行以下命令:

1 2 3 4 5 6 7 8 D:\test>java -jar baksmali-2.0.2.jar -a 16 -x uiautomator.odex -d . Error occured while loading boot class path files. Aborting. org.jf.util.ExceptionWithContext: Cannot locate boot class path file /system/framework/core-junit.odex at org.jf.dexlib2.analysis.ClassPath.loadClassPathEntry(ClassPath.java:217) at org.jf.dexlib2.analysis.ClassPath.fromClassPath(ClassPath.java:161) at org.jf.baksmali.baksmali.disassembleDexFile(baksmali.java:59) at org.jf.baksmali.main.main(main.java:274)

以上的異常表明,反編譯的過程缺少依賴包/system/framework/core-junit.odex,那就從系統中提取。

1 2 3 4 5 6 D:\test>adb pull /system/framework/core-junit.odex # 重複 D:\test>java -jar baksmali-2.0.2.jar -a 16 -x uiautomator.odex -d . # 如果還有缺失的依賴包,則反覆從手機上提取

反編譯 uiautomator.odex 總共需要使用到以下依賴包:

1 2 3 D:\test>ls *.odex android.policy.odex  bouncycastle.odex  core.odex  framework.odex   sec_edm.odex    services.odex apache-xml.odex      core-junit.odex    ext.odex   framework2.odex  seccamera.odex  uiautomator.odex

baksmali 執行成功後,會產生一個 out 目錄,裡面放的是中間檔案。這時,可以使用這些中間檔案來生成dex檔案:

1 2 3 4 5 D:\test>java -jar smali-2.0.2.jar -a 16 -o classes.dex out ## 解壓 dex2jar 到 test 目錄 D:\test\dex2jar-0.0.9.15>d2j-dex2jar.bat ..\classes.dex dex2jar classes.dex -> classes-dex2jar.jar

classes-dex2jar.jar 便是我們要得到java jar包。通過JD Compiler開啟這個jar可以看到反編譯後的java內容。

之所以反編譯 uiautomator,是因為Android SDK中給出的 uiautomator.jar 包中很多API都沒有包含其中,也沒有在其官方文件中給予說明。通過閱讀 uiautomator 的原始碼,發現它有很多可以擴充套件的地方