最近突然有個需求,將很久前的某個版本重新發(fā)布到線上聋迎,經(jīng)過長時間的迭代脂矫,gradle plugin的變遷以及插件化和模塊遠程依賴導(dǎo)致項目結(jié)構(gòu)發(fā)生了巨大的變化,想要直接找回某個版本的代碼成功的運行起來比較困難霉晕,不過還好只是修改版本號以及渠道庭再,所以想到了直接使用反編譯改完之后再回編的方式。這篇文章主要是記錄一下整個流程牺堰。
apktool
Apktool是一個逆向android非常有用的工具拄轻,可以用來反編譯apk文件,并且能在修改部分文件后萌焰,重新打包成一個新的apk哺眯,首選我們需要下載一個apktool的jar包,下載地址扒俯,下載之后把名稱改成apktool.jar奶卓,然后新建一個bat腳本,內(nèi)容是
if "%PATH_BASE%" == "" set PATH_BASE=%PATH%
set PATH=%CD%;%PATH_BASE%;
chcp 65001 2>nul >nul
java -jar -Duser.language=en -Dfile.encoding=UTF8 "%~dp0\apktool.jar" %*
這樣準備工作就完成了
反編譯生成目標文件
然后我們準備一個apk文件撼玄,在同一個目錄下執(zhí)行下面的命令
apktool.bat d -o apk.out source.apk
apk.out是反編譯之后生成的文件夾夺姑,source.apk就是準備的原apk文件名稱,執(zhí)行命令之后生成的apk.out目錄如下
修改版本號及Manifest文件
有了這個apk.out就能修改里面的東西了掌猛,最難修改的部分就是java代碼盏浙,這里對應(yīng)的是smali相關(guān)的文件夾,需要了解一些smali的語法才行荔茬。
修改應(yīng)用版本號只需要修改apktool.yml
最下面的versionCode和versionName就是我們要修改的部分废膘,這里直接改動成最新的版本號和code就行,
另一個是渠道名慕蔚,這個存儲在Manifest文件夾下丐黄,Android的Manifest文件有兩個,一個是外面的AndroidManifest.xml孔飒,這個不是亂碼的,經(jīng)過了apktool的特殊處理,還有一個在original文件夾下的AndroidManifest.xml莉撇,這個和一般的解壓apk拿到的是一樣的先慷,打開會發(fā)現(xiàn)亂碼,這個是android的xml文件的特殊結(jié)構(gòu)導(dǎo)致的,可以自行下載一個AXMLPrinter2.S.jar,然后使用下面的命令就能生成一個非亂碼的文件xxx.txt
java -jar AXMLPrinter2.S.jar AndroidManifest.xml > xxx.txt
同樣的找到需要修改的渠道名key之后,將value改為想要修改的渠道名
回編apk
然后就是再使用下面的命令行逾柿,可以將我們的apk.out文件夾重新編成一個apk文件,也就是下面的dst.apk
apktool.bat b -o dst.apk apk.out
重簽名以及內(nèi)存對齊
拿到新的apk之后蛛勉,最后還需要兩步鹿寻,一是重簽名,直接把簽名的keystore拷貝過來诽凌,執(zhí)行下面的命令
jarsigner -verbose -keystore xxx.keystore -signedjar dst_signed.apk dst.apk keyAlias
然后輸入密碼就行毡熏,生成的簽名apk就是 dst_signed.apk
最后還有一個字節(jié)對齊的工具zipalign.exe,這個在sdk的build-tools的版本下面侣诵,zipalign主要是用來用APK文件提供優(yōu)化痢法,目的是確保所有未壓縮的數(shù)據(jù)以相對于文件的開始對齊。具體來說杜顺,它會導(dǎo)致APK中的所有未壓縮數(shù)據(jù)(如圖像或原始文件)在4字節(jié)邊界上對齊财搁。這允許所有的部分文件都能直接使用mmap進行訪問,即使是包含具有對齊限制的二進制數(shù)據(jù)躬络,這樣會減少運行應(yīng)用程序時消耗的內(nèi)存量尖奔。
zipalign的使用環(huán)節(jié)分為兩種情況,如果使用的是上面這種jarsigner穷当,那么就需要在簽名之后再進行對齊提茁,如果使用的是apksigner,那么就需要先執(zhí)行zipalign馁菜,然后再簽名茴扁,順序相反的話簽名就會失效,我們可以通過以下命令判斷一個apk汪疮,是否文件對齊
zipalign -c -v 4 dst.apk
執(zhí)行完之后峭火,會輸出一些數(shù)據(jù)
可以看到這個剛剛簽名之后的apk文件,并沒有驗證通過智嚷,內(nèi)部許多文件都是有問題的卖丸,然后我們執(zhí)行以下對齊
zipalign -v 4 dst_signed.apk dst_signed_align.apk
這樣就是文件對齊之后的正確版本,一整套的流程基本就結(jié)束了
最后
我們剛才通過修改apktool.yml文件修改了apk的版本號盏道,可以通過aapt工具看看新的apk的版本號是不是真的修改成功了
aapt dump badging dst_signed_align.apk
aapt的工具也在sdk的build-tools文件下面
可以看到版本號確實已經(jīng)修改了稍浆,通過這種方式就達到了修改apk的目的,當然如果想要修改java代碼,那么還需要學(xué)習(xí)smali相關(guān)的語法粹湃。