odex 是 Optimized dex 的縮寫赁温,是優(yōu)化后的dex文件坛怪,通過將 apk 中的 dex 文件進行 odex 優(yōu)化,可以提升程序的啟動速度股囊,同時減小空間的占用
odex 文件依賴系統(tǒng)中已經編譯好的系統(tǒng)模塊袜匿,一般是 /system/framwork 目錄下的 jar 包,目的也是為了提高虛擬機的運行速度稚疹,可以說從 class 到 dex 是針對 Android 平臺的一種通用優(yōu)化沉帮,odex 是 dex 文件在不同手機上做的特殊優(yōu)化
為了反編譯 odex 我們需要準備以下工具
-
smali/baksmali
baksmali-xxx.jar 將 odex 轉換為 smali 文件 (有興趣的可以了解一下 smali 語法)
smali-xxx.jar 將 smali 文件打包成 dex 文件 -
dex2jar
dex2jar 是將 dex 文件轉換為 jar -
Java Decompiler
這個工具是將 jar 里面你的 class 轉換為 java 文件,當然也可以不轉換贫堰,直接使用 jd-gui 程序打開 classes.jar 看里面的內容
這里下載的 smali 版本是 baksmali-2.1.3.jar 和 smali-2.1.3.jar穆壕,不同版本使用方法大同小異
開工,我們先建立一個工作目錄其屏,我這里是創(chuàng)建了一個 deodex 的目錄喇勋,然后把相關工具都放進去,因為反編譯 odex 需要依賴 /system/framework 目錄下的一些東西偎行,所以這里直接把整個 framewrok 目錄拉出來
$ mkdir deodex
$ cd deodex
$ adb pull /system/framework .
當然這一步不是必須的川背,如果在反編譯過程中沒有報缺失依賴文件的錯誤是不需要的
然后從系統(tǒng)目錄中拉出一個程序的 odex 如下
$ adb pull /system/app/LeEcoCircle/oat/arm/LeEcoCircle.odex .
目錄結構如下 (mac 下,目錄結構生成使用 tree 命令蛤袒,安裝:brew install tree熄云,然后在當前目錄執(zhí)行 tree 即可)
deodex
├── LeEcoCircle.odex
├── baksmali-2.1.3.jar
├── dex2jar-2.0
│ ├── ...
├── framework
│ ├── ...
├── jd-gui-osx-1.4.0
│ ├── ...
└── smali-2.1.3.jar
接下來開始反編譯,先使用如下命令
$ java -jar baksmali-2.1.3.jar -x LeEcoCircle.odex
-x 參數是指定 odex 文件
上面命令通常會報錯
Error occurred while loading boot class path files. Aborting.
org.jf.util.ExceptionWithContext: Cannot locate boot class path file /system/framework/core.jar
...
意思是:找不到 /system/framework/core.jar 妙真,這個 jar 是在 /system/framework/arm/boot.oat 中缴允,當然 boot.oat 不只包含 core.jar ,還有 framework.jar 珍德,core-libart.jar 等一系列 jar所以我們將命令改變一下
$ java -jar baksmali-2.1.3.jar -x LeEcoCircle.odex -d framework/arm/ -c framework/arm/boot.oat
-d 參數 指定 bootclasspath 查找的目錄练般,如果不加這個參數,默認是當前目錄
-c 參數 指定 bootclasspath 中具體的 jar/oat 文件
此時锈候,命令不會報 Aborting 的錯薄料,可能會出現一些異常,某些函數不能被解析泵琳,但是還是能夠順利完成 odex 反編譯摄职,生成的 smali 文件放在了當前目錄的 out 目錄中
下一步就是將 smali 文件打包為 dex誊役,使用以下命令
$ java -jar smali-2.1.3.jar out -o classes.dex
會在當前目錄生成 classes.dex 文件,然后執(zhí)行下面命令來反編譯 dex 文件
$ cp classes.dex dex2jar-2.0
$ cd dex2jar-2.0
$ ./dex2jar.sh classes.dex
完成后谷市,會在 dex2jar-2.0 目錄生成 classes-dex2jar.jar 接下來就可以使用 jd-gui 打開直接查看里面的內容了
上面反編譯 odex 是單 dex 的情形势木,如果這個 odex 是由多個 dex 優(yōu)化合成的產物的話,在 baksmali 命令中還需要加入 -e 參數來指定反編譯哪一個 dex歌懒,然后 -o 指定不同的輸出目錄啦桌,不同的目錄是為了生成對應的 dex 文件,如果把他們都輸出到同一個目錄及皂,在執(zhí)行 smali 命令時甫男,可能會失敗,比如:方法數超過 65k 等
參考資料
深入理解Android之Java虛擬機Dalvik 鄧凡平老師之作
convert odex file to dex file
DeodexInstructions