學習的方式有很多種,Read the fucking source code 絕對不失為最佳的方式。除了閱讀 Android SDK 的原始碼,還能通過反編譯 APK 的方式,閱讀他人開發的應用原始碼。本文就來聊聊在 Mac 環境下如何藉助第三方工具反編譯 APK 壓縮檔案(通過愛加密、360加固等手段處理的 APK 檔案除外),閱讀原始碼、修改原始碼並重新打包成一個新的 APK 安裝檔案。
準備工具
本文描述的反編譯手段需要藉助三個工具,分別是:apktool、dex2jar 和 jd-gui,下面我一一介紹下他們的下載及配置過程。
apktool
-
開啟 apktool 指令碼連結網頁,右鍵儲存為一個命名為 apktool 的檔案,記得不要新增任何格式字尾;
-
開啟 apktool.jar 下載連結,下載最新版本,下載完成之後重新命名為 apktool.jar;
-
開啟命令列工具,使用 cp 命令將前面兩步下載的 apktool 指令碼檔案和 apktool.jar 檔案複製到 PC 的 /usr/local/bin 目錄下 (複製前的檔案至此可以刪除),如:
sudo cp apktool apktool.jar /usr/local/bin複製程式碼
-
使用 chmod 命令為上一步複製過去的兩個檔案新增可執行許可權,如:
chmod +x apktool apktool.jar複製程式碼
-
操作至此,便可以在任一路徑下使用 apktool 命令了。現在,你就可以使用 apktool -version 命令檢查以上過程是否配置正確。
有關 apktool 工具的詳細資訊,可以參考官網介紹:A tool for reverse engineering Android apk files。
dex2jar
-
你可以從 softpedia 或者 sourceforge 網站找到 dex2jar 的 Mac 版下載連結,並解壓縮;
-
同樣使用 chmod 命令修改 sh 檔案的使用者許可權,如:
chmod a+x *.sh複製程式碼
jd-gui
從 softpedia 或者 jd.benow.ca/ 網站下載並解壓縮即可,裡面的 JD-GUI 檔案便是閱讀 jar 包的應用程式。
反編譯 apk 資原始檔
apk 檔案就是一個壓縮檔案,通過解壓縮工具便可以開啟並解壓縮。但是裡面的資原始檔,除了 drawable 圖片資源,其他都是經過編譯處理的二進位制檔案,什麼也看不出來。
而使用 apktool 工具可以直接從 apk 檔案中反編譯出諸如 AndroidManifest.xml 、layout、strings 等資原始檔,可以直接修改,供再次打包。如:
apktool d example.apk複製程式碼
反編譯 java 原始碼檔案
解壓縮 apk 檔案,可以看到 classes.dex 原始碼檔案,可能不止一個。通過 dex2jar 工具可以將其轉化為 jar 檔案,並使用 jd-gui 工具開啟並閱讀應用原始碼。
第一步,dex2jar 操作,得到 classes-dex2jar.jar 檔案。注意 d2j-dex2jar.sh 和 classes.dex 檔案的路徑,按需修改:
sh d2j-dex2jar.sh classes.dex複製程式碼
第二步,使用 jd-gui 開啟 classes-dex2jar.jar 檔案,便可以看到目標應用所用到的第三方 library 和 開發原始碼,如:
如果對方開發人員在工程中開啟了混淆功能,將會增加你的閱讀難度,不過仔細分析,也能找到一些蛛絲馬跡,給予你一些“靈感”。
當然,也可以直接針對 apk 檔案使用 dex2jar 命令獲取 jar 檔案,減少上述 apk 檔案解壓縮的這一步驟,如:
sh d2j-dex2jar.sh example.apk複製程式碼
重新打包 apk 安裝檔案
學會如何反編譯 apk 檔案後,我們還可以修改 apk 檔案中的內容,比如應用名稱、桌面圖示,甚至是 Java 原始碼等,然後使用 apktool 工具重新打包,產生一個新的 apk 安裝檔案。
這裡以修改應用名稱和桌面圖示為例,看看如何重新打包 apk 檔案並安裝至手機上。(此處僅供學習參考,勿作惡!)
第一步,使用前文介紹的反編譯 apk 資原始檔的方式得到反編譯後的資料夾,開啟 AndroidManifest.xml 檔案,找到 application 標籤的 label 和 icon 屬性。這樣,我們就知道在哪裡修改對應的資原始檔了;
第二步,找到對應的 drawable 圖示檔案和 strings 字串資源,比如 ic_launcher.png 和 app_name,替換圖示並修改字串內容;
第三步,使用 apktool b files
命令編譯打包,這裡的 files 對應第一步反編譯 apk 檔案時得到的應用資料夾。執行完畢,便會得到一個新的 apk 檔案;
注意:此時得到的 apk 檔案是沒有沒有經過簽名的,使用 adb install 命令安裝時會得到一個失敗提示:Failure [INSTALL_PARSE_FAILED_NO_CERTIFICATES]。
第四步,生成自己的簽名檔案。你可以選擇使用 Android Studio -> Build -> Next -> Create New… 視覺化操作介面生成一個新的簽名檔案,也可以直接使用 keytool 工具直接在終端工具上生成,如:
keytool -genkey -keystore example.keystore -keyalg RSA -validity 10000 -alias example複製程式碼
第五步,使用 jarsigner 工具為 apk 檔案簽名,簽名過後得到的 apk 檔案便可以使用 adb install 命令安裝至連線到 PC 的安卓裝置上了。簽名命令如下:
jarsigner -verbose -keystore example.keystore -signedjar example-signed.apk example.apk example複製程式碼
注意:如果簽名過後的 apk 檔案依舊安裝失敗,可以試試在簽名命令上加上
-digestalg SHA1 -sigalg MD5withRSA -tsa
引數。當然這裡我在測試時沒有新增該引數,但也能正常安裝。
修改資原始檔並重新打包還是比較簡單的,但是修改 java 原始碼再重新打包就比較複雜了,特別是在改動較大的情況下。「鴻洋」大神有一篇文章,描述瞭如何反編譯 apk 併為其新增啟動頁廣告的過程,當然也沒有涉及到原開發人員的 Java 原始碼改動,詳情可參考: Android 反編譯初探 應用是如何被注入廣告的。
歡迎關注
本文由 亦楓 創作並首發於 亦楓的個人部落格 ,同步授權微信公眾號:技術鳥(NiaoTech)。
歡迎各種形式地交流與轉載,註明作者及出處即可。
本文標題為: Android Apk 檔案反編譯和重新打包的過程分析
本文連結為:yifeng.studio/2016/12/05/…