首先明確,反編譯別人apk是一件不厚道的事情。代碼是程序員辛苦工作的成果,想通過這種手段不勞而獲,是不對的。這也說明,代碼混淆是非常重要的。本文抱着學習的態度,研究在一些特殊的情況下如果有需要,該怎么反編譯apk。
工具簡介
apktool,編譯和反編譯apk,從apk中提取圖片和布局資源
dex2jar,將可運行文件classes.dex反編譯為jar源碼文件
jd-gui,查看jar源碼文件
反編譯
apktool安裝
Windows系統:
1. 首先確保系統安裝有Java
2. 下載apktool.bat腳本
3. 下載最新版本的apktool.jar,並且重命名為apktool.jar
4. 將apktool.bat和apktool.jar放在同一目錄下,就可以在命令行窗口使用了。
5. 其他系統請參考鏈接
用法
可以直接在命令行執行apktool.bat查看幫助。這里介紹兩個最常用的:
反編譯
apktool.bat d -o <output_dir> test.apk
其中<output_dir>指定輸出目錄,默認為apk.out。
編譯
apktool.bat b -o <output.apk> <input_dir>
其中<input_dir>就是上面反編譯輸出的目錄,<ouput.apk>是編譯的輸出結果,默認為dist/<name>.apk。
示例
一個典型的apktool反編譯的結果如下:
此時,可以查看AndroidManifest.xml,res及smali文件了。甚至可以修改這個目錄下的資源文件或者smali文件,然后重新編譯。
值得注意的是,apktool反編譯出來只能得到apk的smali文件,即匯編語言版本,並不能得到源代碼。
查看源碼
一. 這里需要用到另外兩個工具,下載dex2jar並解壓。下載jd-gui,這是一個帶UI的應用程序。
二. 將需要反編譯的apk的后綴名改為.zip或者.rar,然后解壓到一個文件夾,得到其中的classes.dex文件。
三. 將classes.dex復制到解壓后的dex2jar-2.0文件夾下。從命令行進入到該目錄,執行
d2j-dex2jar.bat classes.dex
會生成由classes.dex反編譯得到的jar文件,classes-dex2jar.jar。
四. 然后使用jd-gui打開classes-dex2jar.jar,就可以查看源碼了。
如果apk在發布的時候加過混淆處理,那么我們也只能得到混淆后的版本。想通過閱讀源碼來破解別人的apk,還是有一些難度的。
修改代碼
如果只是修改apk相應的資源,例如圖片,比較好辦,在res文件夾下找到相應的文件替換就可以。
修改代碼比較麻煩,因為反編譯出來的結果中只有smali文件,即Java虛擬機支持的匯編語言。
如果確實需要修改代碼,就得對照smali文件和從classes.dex反編譯出來的源碼了,按照smali的規范來改動即可。相當於寫匯編,這個難度比較大。
重新打包
使用apktool編譯前面反編譯生成的目錄即可。
簽名
簽名是對要發布的apk文件作標記,確保你的apk文件有唯一的身份歸屬認證,只有相同簽名和相同包名的文件才可以覆蓋安裝並保留用戶信息。
對於反編譯的apk,我們可以通過jarsigner來對它進行簽名。
生成keystore文件
首先,簽名需要keystore文件,可以使用keytool工具生成,一般Java環境都帶有keytool命令,可以在命令行測試。
keytool -genkey -alias demo.keystore -keyalg RSA -validity 40000 -keystore demo.keystore
各個參數解釋如下:
-genkey 產生證書文件
-alias 產生別名
-keystore 指定密鑰庫的.keystore文件中
-keyalg 指定密鑰的算法,這里指定為RSA(非對稱密鑰算法)
-validity 為證書有效天數,這里我們寫的是40000天
輸入上述命令后,會有如下的提示:
輸入密鑰庫口令: 密鑰庫口令太短 - 至少必須為 6 個字符 輸入密鑰庫口令: 再次輸入新口令: 您的名字與姓氏是什么? [Unknown]: test 您的組織單位名稱是什么? [Unknown]: test 您的組織名稱是什么? [Unknown]: 您所在的城市或區域名稱是什么? [Unknown]: 您所在的省/市/自治區名稱是什么? [Unknown]: 該單位的雙字母國家/地區代碼是什么? [Unknown]: CN CN=test, OU=test, O=Unknown, L=Unknown, ST=Unknown, C=CN是否正確? [否]: y
輸入 <demo.keystore> 的密鑰口令
(如果和密鑰庫口令相同, 按回車):
簽名apk
jarsigner也存在於Java JDK的安裝包當中,所以安裝好了Java環境的話,可以直接在命令行使用。
jarsigner -verbose -keystore demo.keystore demo.apk demo.keystore
-verbose 指定生成詳細輸出
-keystore 指定數字證書存儲路徑
這樣,就完成了對一個apk的簽名過程,然后就可以安裝使用了。注意如果你的手機上原來就有這個apk,需要卸載掉。因為新apk的簽名已經改變了。