背景介紹:最近在做Robotium自動(dòng)化測(cè)試,使用到solo.takeScreenshot()函數(shù)以在測(cè)試過(guò)程中截圖,但此函數(shù)需要被測(cè)試APP具有<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />權(quán)限。在只有被測(cè)試APP的apk文件的情況下,修改apk文件后綴名為zip,解壓縮后,修改AndroidManifest.xml文件,刪除META-INF文件夾,重壓縮為apk文件后,再簽名就可以了。
但是!本文舍近求遠(yuǎn),借機(jī)對(duì)apk文件進(jìn)行反編譯與重編譯、重簽名,來(lái)修改源代碼中的AndroidManifest.xml文件。本文這么做的目的,就是想熟悉一下反編譯、重編譯和重簽名的過(guò)程。
1.請(qǐng)下載反編譯、重編譯工具Apktool
在https://code.google.com/p/android-apktool/downloads/list下載apktool需要依賴的jar和apktool腳本文件。以windows用戶為例,下載前兩個(gè)文件:


3.將cmd定位至apktool.bat所在文件夾中,輸入apktool.bat將出現(xiàn)所有的參數(shù)解釋。
4.我們先來(lái)進(jìn)行反編譯apk的過(guò)程:
在命令行中輸入apktool.bat d -f <apk文件路徑/apk文件> <目標(biāo)文件夾>
參數(shù)解釋 d:decompile,進(jìn)行反編譯
-f:強(qiáng)制清空目標(biāo)文件夾內(nèi)已存在的內(nèi)容
例如:

5.進(jìn)入生成的文件夾,assets和res文件夾中都已經(jīng)生成了app用到的xml和素材
lib文件夾里包含了交叉編譯庫(kù)
smali文件夾里包含了反編譯出的smali文件
而AndroidManifest.xml正是我們需要修改的東西(為什么要修改它?見(jiàn)背景介紹)
這里順便解釋一下odex文件和dex文件。
dex文件:Dex是Dalvik VM executes的全稱,即Android Dalvik執(zhí)行程序,并非Java的字節(jié)碼而是Dalvik字節(jié)碼,16進(jìn)制機(jī)器指令。
odex文件:將dex文件依據(jù)具體機(jī)型而優(yōu)化,形成的optimized dex文件,提高軟件運(yùn)行速度,減少軟件運(yùn)行時(shí)對(duì)RAM的占用。
smali文件:將dex文件變?yōu)榭勺x易懂的代碼形式,反編譯出文件的一般格式。
6.往AndroidManifest.xml里面加入<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
7.開(kāi)始重編譯吧。在命令行中輸入apktool.bat b <反編譯出的文件夾>
參數(shù)解釋:b:build,重編譯
例如:

8.進(jìn)入目標(biāo)文件夾,新生成了build文件夾和dist文件夾
build文件夾里包含了重編譯生成apk文件所產(chǎn)生的過(guò)渡文件,包括dex文件,資源文件等
dist文件夾則包含了重編譯生成的apk文件
9.這時(shí)候生成的apk文件還無(wú)法直接安裝到手機(jī)上。否則,會(huì)出現(xiàn)INSTALL_PARSE_FAILED_NO_CERTIFICATES錯(cuò)誤:

出現(xiàn)這個(gè)錯(cuò)誤的原因是:
每個(gè)安裝的apk必須包含簽名。簽名的其中一個(gè)作用就是驗(yàn)證該apk安裝包是否是個(gè)合法的安裝包。我們?cè)诮?jīng)過(guò)反編譯-修改-重編譯的過(guò)程后,生成的apk是不包含簽名的。在安裝apk的過(guò)程中,手機(jī)未檢測(cè)到apk中的簽名,所以提示INSTALL_PARSE_FAILED_NO_CERTIFICATES錯(cuò)誤。
關(guān)于Android簽名,可以參考:http://www.blogjava.net/zh-weir/archive/2011/07/19/354663.html。
In a word, Android簽名機(jī)制不能阻止APK包被修改,但修改后的再簽名無(wú)法與原先的簽名保持一致。(擁有私鑰的情況除外)。
10.接下來(lái),我們就要重編譯的apk文件進(jìn)行簽名
可以使用re-sign.jar。re-sign-jar下載地址:https://dl.dropboxusercontent.com/u/5055823/re-sign.jar
雙擊,將未簽名的apk拖進(jìn)UI界面,過(guò)一會(huì)兒就會(huì)提示你保存簽名過(guò)的apk了。(第一次使用需要設(shè)置ANDROID_HOME和JAVA_HOME環(huán)境變量)