引入
DEX文件在Android中很重要,它與APK瘦身、熱修復、插件化、應用加固、逆向工程、64K方法數限制都有關係[1]。
所以,我們先來認識一下本文的主角,DEX文件。
Dalvik虛擬機在Android中的作用,與JVM在Linux中的作用類似。我們用java語言來開發Android程序,但Android的Dalvik並不能直接運行java字節碼(.class文件)。所以需要把.class文件轉換爲DEX文件。轉換過程如下:
如圖可見,DEX文件可以認爲是多個.class文件轉換而來的。DEX文件可以直接在Android下運行。
下面我們就講解如何將.java文件轉換爲.dex文件,並在Android下運行這個.dex文件。
本文實驗環境
- windows 10
- android studio
- JDK 1.8.0
步驟
- 寫出如下java代碼,並將其保存爲Hello.java
public class Hello
{
public static void main(String[] args)
{
System.out.println("hello ybdesire");
}
}
- 添加build-tools的環境變量
由上面圖1可知,要將.class文件轉換爲.dex文件,必須要用dx工具。dx一般位於Android SDK的build-tools中。所以需要把dx工具的路徑,添加到Windows系統的環境變量中,本文的build-tools路徑爲C:\Users\xxx\AppData\Local\Android\Sdk\build-tools\28.0.3
。
- 將.java轉換爲.class
使用javac命令(JDK的路徑中),可以將.java文件轉換爲.class文件。
E:\java_to_dex>javac Hello.java
E:\java_to_dex>java Hello
hello ybdesire
使用java命令,可以運行.class文件,並得到結果。
- 將.class文件轉換爲.dex文件
做了如上配置後,使用如下的dx命令,可以將.class文件轉換爲.dex文件
E:\java_to_dex>dx --dex --output=Hello.dex Hello.class
- 在Android環境中運行.dex文件
首先打開Android模擬器,或連接真機。如下出現devices的顯示,就說明能連接Android。
E:\java_to_dex>adb devices
List of devices attached
emulator-xxxx device
使用adb,將.dex文件push到Android端。
E:\java_to_dex>adb root
E:\java_to_dex>adb push Hello.dex /sdcard/
Hello.dex: 1 file pushed. 0.1 MB/s (728 bytes in 0.013s)
再進入shell,使用如下的dalvikvm命令,就能運行.dex文件。
E:\java_to_dex>adb shell
generic_x86:/ $ dalvikvm -cp /sdcard/Hello.dex Hello
hello ybdesire
本文實驗代碼可以在這裏獲取:
- https://github.com/ybdesire/android_security_learn/tree/master/compile_build/build_dex_from_java_and_run
思考
- 上面講了一個很簡單的java文件轉換爲dex在Android運行,是否可以直接從APK中抽出DEX並在Android運行呢?
答案是不行的。從兩個方面考慮:首先,dalvikvm命令運行DEX必須要指定class name,任意APK中抽出的classes.dex我們無法獲取class name;其次,APK中除了DEX,還有資源文件,動態鏈接庫等,缺一不可。
參考
- [1] https://juejin.im/post/5bf22bb5e51d454cdc56cbd5
- [2] https://github.com/ybdesire/android_security_learn/tree/master/compile_build/build_dex_from_java_and_run