在android開發中經常會遇到需要反編譯競品的需求,題主也就針對反編譯apk后替換sdk后重新打包的場景進行試驗,下面一步一步來說明Android如何反編譯后重新打包。
一個典型apk包中包含的內容
我們知道android項目編譯成應用程序后的安裝文件是.apk文件,運行期間classloader加載的是dex文件中的class。所以我們先來看看一個典型的apk包中具有哪些基本內容:
方式一:使用apktool直接反編譯apk(酷市場為例,2016.8.12更新)
配置apktool環境:
1.打開apktool官網
2.下載執行腳本文件和apktool.jar包
先下載腳本文件 :
mac os 對應 apktool.sh
windows 對應 apktool.bat
再下載最新的apktool.jar
3.配置apktool的運行環境
windows:把下載的兩個文件都copy到c:/windows目錄,或者放到自己指定的目錄下再修改系統path也行
Mac os: 把下載的兩個文件都copy到/usr/local/bin目錄下,修改權限為可執行chmod a+x
在命令行終端模式下,輸入apktool驗證是否完成apktool環境配置
反編譯apk包
1.命令行進入到apk包所在的文件夾路徑
2.執行反編譯命令
apktool d filename
3.得到反編譯后的文件夾
4.修改apk內容(舉例替換logo)
查看manifest.xml文件,icon對應的就是配置應用logo
logo圖片資源所在
5.重新簽名打包
1.回編譯apkapktool b files
files就是對應剛剛修改的apk文件夾,執行完后會重新生成一個apk文件
注意:編譯后的apk是安裝不成功的,總是提示
Failure [INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION]
,實質是沒簽名。
2.生成簽名:
keytool -genkey -keystore coolapk.keystore -keyalg RSA -validity 10000 -alias coolapk
注意:上面-keystore后面跟的是簽名文件的名字,而-alias是別名,一般情況下-keystore后面跟-alias是一樣的,但其實兩者沒有關系,這也是我故意搞成不一樣的原因。
3.為apk增加簽名:
jarsigner -digestalg SHA1 -sigalg MD5withRSA -tsa -verbose -keystore coolapk.keystore -signedjar coolapk-signed.apk coolapk.apk coolapk
注意:
1.最后的”coolapk”就是-alias后面帶的,必須保持一致
2.如果不帶-digestalg SHA1 -sigalg MD5withRSA簽名后的apk安裝也會不成功,INSTALL_PARSE_FAILED_NO_CERTIFICATES的錯誤,如果不帶-tsa會報一個時間方面的警告.
方式二:使用dex2jar反編譯查看java代碼(為例,2016.4月更新)
下載dex2jar和jd-gui
dex2jar: https://github.com/pxb1988/dex2jar
jd-gui: http://jd.benow.ca/
使用dex2jar將從apk中解壓得到的dex文件轉成jar包
使用jd-gui來查看jar包內容
將要需改的類更改代碼后復制到jar內,完成覆蓋替換
把jar包重新轉成dex文件
將修改完成后的dex文件復制到原來的apk文件中
直接覆蓋原來的dex文件
然后就興沖沖地直接去安裝了,然而~
看來果然沒這么簡單就能呢個搞定,繼續排查原因。
找原因
看看apk文件中有什么可疑對象導致了安裝失敗,果然除了dex和資源文件以外,還發現了三個文件
原來是apk包本身的防篡改機制導致的
打開文件來一探究竟,果然里面都是對打包時對文件進行了標識記錄,看來這是避免文件被篡改的安全機制。
找到問題原因就來解決,嘿咻嘿咻
想想既然是這些文件導致的,那先試試簡單粗暴地直接把文件刪了,避免防篡改檢查
然而,這樣的是不行的,必須要有這個文件夾才能解析apk包,可能這些相當于是讀取安裝文件列表清單,必須具有,看來此路不通,
既然原來的清單內容對不上,但又不能不提供,那能不能我們給它配一個新的?
想到這里,感覺可以動手試試,嘿咻嘿咻~
這些文件既然是在編譯打包成apk時期自動生成的,那要想再生成一份新的,所以應該重新打包就可以。可是這個本身已經就是apk文件了,怎么再編譯打包?
停下來想了想,對啊,突然想起來可以給包簽個名唄,打簽名應該也會有同樣的效果才對,繼續嘿咻嘿咻。
找個工具來簽名吧,用自己的去簽名留下點什么不良記錄就不好了,嘿嘿~