背景介紹:最近在做Robotium自動化測試,使用到solo.takeScreenshot()函數以在測試過程中截圖,但此函數需要被測試APP具有<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />權限。在只有被測試APP的apk文件的情況下,修改apk文件后綴名為zip,解壓縮后,修改AndroidManifest.xml文件,刪除META-INF文件夾,重壓縮為apk文件后,再簽名就可以了。
但是!本文舍近求遠,借機對apk文件進行反編譯與重編譯、重簽名,來修改源代碼中的AndroidManifest.xml文件。本文這么做的目的,就是想熟悉一下反編譯、重編譯和重簽名的過程。
1.請下載反編譯、重編譯工具Apktool
在https://code.google.com/p/android-apktool/downloads/list下載apktool需要依賴的jar和apktool腳本文件。以windows用戶為例,下載前兩個文件:
3.將cmd定位至apktool.bat所在文件夾中,輸入apktool.bat將出現所有的參數解釋。
4.我們先來進行反編譯apk的過程:
在命令行中輸入apktool.bat d -f <apk文件路徑/apk文件> <目標文件夾>
參數解釋 d:decompile,進行反編譯
-f:強制清空目標文件夾內已存在的內容
例如:
5.進入生成的文件夾,assets和res文件夾中都已經生成了app用到的xml和素材
lib文件夾里包含了交叉編譯庫
smali文件夾里包含了反編譯出的smali文件
而AndroidManifest.xml正是我們需要修改的東西(為什么要修改它?見背景介紹)
這里順便解釋一下odex文件和dex文件。
dex文件:Dex是Dalvik VM executes的全稱,即Android Dalvik執行程序,并非Java的字節碼而是Dalvik字節碼,16進制機器指令。
odex文件:將dex文件依據具體機型而優化,形成的optimized dex文件,提高軟件運行速度,減少軟件運行時對RAM的占用。
smali文件:將dex文件變為可讀易懂的代碼形式,反編譯出文件的一般格式。
6.往AndroidManifest.xml里面加入<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
7.開始重編譯吧。在命令行中輸入apktool.bat b <反編譯出的文件夾>
參數解釋:b:build,重編譯
例如:
8.進入目標文件夾,新生成了build文件夾和dist文件夾
build文件夾里包含了重編譯生成apk文件所產生的過渡文件,包括dex文件,資源文件等
dist文件夾則包含了重編譯生成的apk文件
9.這時候生成的apk文件還無法直接安裝到手機上。否則,會出現INSTALL_PARSE_FAILED_NO_CERTIFICATES錯誤:
出現這個錯誤的原因是:
每個安裝的apk必須包含簽名。簽名的其中一個作用就是驗證該apk安裝包是否是個合法的安裝包。我們在經過反編譯-修改-重編譯的過程后,生成的apk是不包含簽名的。在安裝apk的過程中,手機未檢測到apk中的簽名,所以提示INSTALL_PARSE_FAILED_NO_CERTIFICATES錯誤。
關于Android簽名,可以參考:http://www.blogjava.net/zh-weir/archive/2011/07/19/354663.html。
In a word, Android簽名機制不能阻止APK包被修改,但修改后的再簽名無法與原先的簽名保持一致。(擁有私鑰的情況除外)。
10.接下來,我們就要重編譯的apk文件進行簽名
可以使用re-sign.jar。re-sign-jar下載地址:https://dl.dropboxusercontent.com/u/5055823/re-sign.jar
雙擊,將未簽名的apk拖進UI界面,過一會兒就會提示你保存簽名過的apk了。(第一次使用需要設置ANDROID_HOME和JAVA_HOME環境變量)