我們下載到的 App 安裝包是 Apk 文件(Android Application Package) 。通過 Apk 文件,我們也可以得到這個應用的代碼和資源文件,對應用進行修改。
那麼我們如何獲取這些文件呢?這就需要 Android 反編譯技術。
01 所需要的軟件
- Apktool
反編譯 xml 文件和 dex 文件,並可以將編譯後的項目重新打包成 apk。
官方下載地址: Apktool
官方的速度有時候不穩定,也可以從我的網盤中下載: 鏈接 密碼:xkao
- dex2jar
將 classes.dex 轉換爲「.jar」文件)
官方下載地址: dex2jar
我的網盤: 鏈接 密碼:xkao
- jd-gui
查看「.jar」文件
官方下載地址: jd-gui
我的網盤: 鏈接 密碼:xkao
02 Apktool
我們可以通過 Apktool 可以將 apk 文件進行反編譯,但是直接把 apk 的擴展名改成「.zip」也可以對其進行解壓並得到一些資源文件。
- META-INF 裏保存 App 的簽名信息
- classes.dex
.dex 是 Dalvik 虛擬機上的可執行文件,需要使用 dex2jar 將其轉換爲 jar 文件
- AndroidManifest.xml
Android 清單文件,向 Android 系統提供應用的必要信息。
- assets
存放一些資源文件字體,聲音等。
- lib
存放第三方庫
- original
存放未經過反編譯的等 AndroidManifest.xml 文件
- res
存放資源文件,例如圖片,顏色,字符等。
- smali
smali 裏存放的是 java 編譯成的 smali 代碼,smali 相當於 Android 虛擬機上運行的語言。
直接解壓可以得到一些資源文件,但是 AndroidManifest.xml 和其他的 xml 文件都是亂碼,通過 Apktool 進行反編譯,可以最大限度的還原這些文件的內容。
02 - 1 安裝 Apktool
Windows :
- 到 這裏 或者我的 網盤鏈接 裏下載好 script 腳本文件,修改名稱「apktool.bat」(如果從我的網盤下載,無須修改名稱)
- 到 這裏 或者我的 網盤鏈接 下載 apktool,然後修改名稱爲「apktool.jar」
- 將「apktool.jar」和「apktool.bat」移動到 windows 目錄(一般在 C://windwos 下)
- 在命令行中輸入
$ apktool
如果出現
則說明安裝成功,若沒有出現,則需要把「apktool.jar」、「apktool.bat」的路徑添加到系統的環境變量中。
Mac OS:
- 到 這裏 或者我的 網盤鏈接 裏下載好 script 腳本文件,修改名稱「apktool」(如果從我的網盤下載,無須修改名稱) 。
- 到 這裏 或者我的 網盤鏈接 下載 apktool,然後修改名稱爲「apktool.jar」。
- 把「apktool」、「apktool.jar」移動到
/usr/local/bin
目錄下 - 在命令行中 cd 到
/usr/local/bin
中然後分別輸入下面兩條命令
$ chmod a+x d2j_invoke.sh
$ chmod a+x d2j-dex2jar.sh
- 在命令行中輸入
$ apktool
出現
則安裝成功
02 - 2 反編譯 Apk
- cd 到 apk 的目錄下
- 輸入
$ apktool d test.apk
運行完成後,得到一個包含資源文件和代碼的文件:
注意:
此時 dex 文件直接反編譯成了 smali 文件,而我們需要的是 .dex 文件。
此時再運行:
$ apktool d -s -f test.apk
-d 反編譯 apk 文件
-s 不反編譯 dex 文件,而是將其保留
-f 如果目標文件夾存在,則刪除後重新反編譯
此時得到這樣的文件夾:
02 - 3 打包、簽名新的 Apk
爲了演示如何將修改過後的 Apk 文件重新打包簽名,我寫了一個簡單的 Demo:把 Demo 的背景換了之後,進行打包、簽名。
這是初始應用程序的運行效果:
- 使用 Apktool 反編譯
- 打開生成的目錄進行修改
修改 bg.jpg 爲另一張準備好的圖片(注意前後命名一致)。
- 重新打包
$ apktool b b_test -o newtest.apk
-b 是指 build
b_test 是剛纔反編譯出的文件所在的目錄
-o 用於指定新的文件名稱,這裏指定爲「newtest.apk」
- 得到新的 apk 文件
注意:
此時的 apk 文件是不能安裝的,還需要對其進行簽名。
- 對新的 Apk 進行簽名:
$ jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore testjks -storepass password newtest.apk aliasName
簽名文件是我自己生成的,沒有辦法使用 Apk 原來的簽名進行簽名。
現在將 Apk 安裝一下試試看:
可以看到,背景資源已經成功替換成我們設置的第二張圖片了。
03 dex2jar
下載、解壓好 dex2jar
- 將上一步得到的 classes.dex 文件(有時候還有 classes2.dex,說明方法數過多,把它當成 classes.dex 處理就好了)複製到 dex2jar 解壓好的目錄中。
- 在命令行中運行:
$ sh d2j-dex2jar.sh classes.dex
如果提示:
d2j-dex2jar.sh: line 36: ./d2j_invoke.sh: Permission denied
執行
$ sudo chmod +x d2j_invoke.sh
後再次執行
$ sh d2j-dex2jar.sh classes.dex
運行成功,在當前目錄下生成了 classes-dex2jar.jar 文件。
04 jd-gui
安裝好 jd-gui 之後,用其將 classes-dex2jar.jar 打開,就可以看到反編譯出來的 java 代碼了!
這裏的代碼沒有經過混淆,所以命名容易識別,如果是從應用市場下載下來的 apk 文件,反編譯出來的代碼大部分是混淆過後的代碼。
出於對開發者的尊重和爲了保持應用的穩定,希望大家不要隨意修改別人的應用程序,請僅從技術層面上妥善利用這一技術!
歡迎關注本文作者:
掃碼關注並回復「乾貨」,獲取我整理的千G Android、iOS、JavaWeb、大數據、人工智能等學習資源。