1. 程式人生 > >【轉】Android反編譯apk修改版本號及重簽名流程

【轉】Android反編譯apk修改版本號及重簽名流程

最近突然有個需求,將很久前的某個版本重新發布到線上,經過長時間的迭代,gradle plugin的變遷以及外掛化和模組遠端依賴導致專案結構發生了巨大的變化,想要直接找回某個版本的程式碼成功的執行起來比較困難,不過還好只是修改版本號以及渠道,所以想到了直接使用反編譯改完之後再回編的方式。這篇文章主要是記錄一下整個流程。

apktool

Apktool是一個逆向android非常有用的工具,可以用來反編譯apk檔案,並且能在修改部分檔案後,重新打包成一個新的apk,首選我們需要下載一個apktool的jar包,下載地址,下載之後把名稱改成apktool.jar,然後新建一個bat指令碼,內容是

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檔案,在同一個目錄下執行下面的命令

apktool.bat d -o apk.out source.apk

apk.out是反編譯之後生成的資料夾,source.apk就是準備的原apk檔名稱,執行命令之後生成的apk.out目錄如下

apk.out

修改版本號及Manifest檔案

有了這個apk.out就能修改裡面的東西了,最難修改的部分就是java程式碼,這裡對應的是smali相關的資料夾,需要了解一些smali的語法才行。
修改應用版本號只需要修改apktool.yml


apktool.yml

最下面的versionCode和versionName就是我們要修改的部分,這裡直接改動成最新的版本號和code就行,
另一個是渠道名,這個儲存在Manifest資料夾下,Android的Manifest檔案有兩個,一個是外面的AndroidManifest.xml,這個不是亂碼的,經過了apktool的特殊處理,還有一個在original資料夾下的AndroidManifest.xml,這個和一般的解壓apk拿到的是一樣的,開啟會發現亂碼,這個是android的xml檔案的特殊結構導致的,可以自行下載一個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

重簽名以及記憶體對齊

拿到新的apk之後,最後還需要兩步,一是重簽名,直接把簽名的keystore拷貝過來,執行下面的命令

jarsigner -verbose -keystore xxx.keystore -signedjar dst_signed.apk dst.apk keyAlias

然後輸入密碼就行,生成的簽名apk就是 dst_signed.apk
最後還有一個位元組對齊的工具zipalign.exe,這個在sdk的build-tools的版本下面,zipalign主要是用來用APK檔案提供優化,目的是確保所有未壓縮的資料以相對於檔案的開始對齊。具體來說,它會導致APK中的所有未壓縮資料(如影象或原始檔案)在4位元組邊界上對齊。這允許所有的部分檔案都能直接使用mmap進行訪問,即使是包含具有對齊限制的二進位制資料,這樣會減少執行應用程式時消耗的記憶體量。
zipalign的使用環節分為兩種情況,如果使用的是上面這種jarsigner,那麼就需要在簽名之後再進行對齊,如果使用的是apksigner,那麼就需要先執行zipalign,然後再簽名,順序相反的話簽名就會失效,我們可以通過以下命令判斷一個apk,是否檔案對齊

zipalign -c -v 4 dst.apk

執行完之後,會輸出一些資料


zipalign check

可以看到這個剛剛簽名之後的apk檔案,並沒有驗證通過,內部許多檔案都是有問題的,然後我們執行以下對齊

zipalign -v 4 dst_signed.apk dst_signed_align.apk
verification success

這樣就是檔案對齊之後的正確版本,一整套的流程基本就結束了

最後

我們剛才通過修改apktool.yml檔案修改了apk的版本號,可以通過aapt工具看看新的apk的版本號是不是真的修改成功了

aapt dump badging dst_signed_align.apk

aapt的工具也在sdk的build-tools檔案下面

aapt dump

可以看到版本號確實已經修改了,通過這種方式就達到了修改apk的目的,當然如果想要修改java程式碼,那麼還需要學習smali相關的語法。