一、反編譯工具:
1、APKTool:
APKTool是由GOOGLE提供的APK編譯工具,能夠完成反編譯及回編譯apk的工作。同時,它也有著安裝反編譯系統apk所需要的framework-res框架,以及清理以前反編譯資料夾等功能。
APKTool的使用需要java支援。
2、dex2jar:
dex2jar 是將android的.dex檔案轉換成Java的.class檔案的轉換工具,如果在轉換過程中有問題的話,可以試用下其他的版本。
3、jd-gui:
JD分為JD-GUI、JD-Eclipse兩種執行方式,JD-GUI是以單獨的程式的方式執行,JD-Eclipse則是以一個Eclipse外掛的方式執行。
jd-gui只能檢視,不能夠將那些檔案轉換成.java檔案。
檔案下載地址:https://pan.baidu.com/s/1ucFu7NATp0V3u9ixSwfnng
提取碼:eeir
二、APKTool使用:
下載好的apktool資料夾中包含以下檔案:aapt.exe、apktool.bat、apktool.jar、cmd.exe.
1、反編譯:
將要反編譯的apk檔案複製到該資料夾下,開啟cmd.exe,進入cmd中,執行命令:
apktool.bat d hotword.apk
(不復制也行,但是執行命令時要使用絕對路徑寫清apk檔案放置的精確位置)
在apktool資料夾下可以看到hotword資料夾,裡面儲存的有res下的資原始檔,和各種XML檔案:
如果你給定的apk反編譯檔案已經存在,那麼輸入完該命令後會提示你,並且無法執行,需要重新修改命令加入-f指令:
apktool.bat d –f hotword.apk
這樣會強行覆蓋已經存在的檔案。
2、回編譯:
執行命令:
apktool.bat b hotword
引數b代表回編譯,hotword則是apk反編譯出來的資料夾名。
回編譯完成會在hotword資料夾生成一個dist資料夾和一個build資料夾,dist資料夾裡面存放的就是回編譯後不帶有簽名的apk檔案,build資料夾裡面還有一個apk資料夾,裡面存放的是回編譯後沒有打包成apk的檔案。
如下:
3、安裝特定的framework-res.apk檔案:
install-framework命令,應用於為APKTool安裝特定的framework-res.apk檔案,方便反編譯一些與ROM相互依賴的APK檔案。
三、dex2jar的使用:
1、解壓檔案:
將apk檔案的字尾名改為zip格式,解壓裡面的classes.dex檔案:
將classes.dex放置到dex2jar資料夾下(或使用絕對路徑),執行命令:
d2j-dex2jar.bat classes.dex
得到一個jar包:
四、jd-gui的使用:
開啟jd-gui.exe:
File-》open file···
選中剛才生成的jar包,開啟可得:
五、關於反編譯:
1、什麼是反編譯器 ?
編譯的定義是:將原始碼轉換成二進位制執行程式碼的過程,將C原始碼編譯成exe可執行檔案這樣的就叫做編譯。
反編譯:把二進位制執行程式碼還原成原始碼的過程,把exe轉換為C原始碼就叫反編譯。
像Java、.net這樣基於虛擬機器技術的程式語言則反編譯非常容易,Java平臺下有JD等反編譯器,.net平臺下則有Reflector等反編譯器。但是主流的C的編譯器都進行了程式碼的優化,把C編譯生成的exe檔案反編譯成C程式碼非常困難。
2、反編譯得到的是否是原始碼?
當然不是。
程式碼與原始碼是非常接近的,基本90%還原,但是還是會有一些差異。比如說,原始碼裡的a=2+3;這行程式碼,編譯成apk再反編譯回來,就變成了a=5;不會還原到2+3那種程式碼了。
3、既然程式可以反編譯,那是不是開發安卓程式很不安全,面臨隨時都會被破解的風險?
這倒不至於,開發人員可以採用程式碼混淆等技術,以此來加大反編譯的難度和降低反編譯程式碼的可讀性。
但歸根到底來說,不可能完全避免這種風險,不過可以大大減小,而且jd-gui只能檢視,不能夠將那些檔案轉換成.java檔案。
六、問題解決:
在apktool反編譯的過程中可能出現如下錯誤:
Exception in thread "main" brut.androlib.AndrolibException: Could not decode arsc file
at brut.androlib.res.decoder.ARSCDecoder.decode(ARSCDecoder.java:54)
at brut.androlib.res.AndrolibResources.getResPackagesFromApk(AndrolibResources.java:604)
at brut.androlib.res.AndrolibResources.loadMainPkg(AndrolibResources.java:74)
at brut.androlib.res.AndrolibResources.getResTable(AndrolibResources.java:66)
at brut.androlib.Androlib.getResTable(Androlib.java:49)
at brut.androlib.ApkDecoder.decode(ApkDecoder.java:93)
at brut.apktool.Main.cmdDecode(Main.java:169)
at brut.apktool.Main.main(Main.java:85)
Caused by: java.io.IOException: Expected: 0x001c0001, got: 0x00000000
at brut.util.ExtDataInput.skipCheckInt(ExtDataInput.java:48)
at brut.androlib.res.decoder.StringBlock.read(StringBlock.java:43)
at brut.androlib.res.decoder.ARSCDecoder.readPackage(ARSCDecoder.java:95)
at brut.androlib.res.decoder.ARSCDecoder.readTable(ARSCDecoder.java:81)
at brut.androlib.res.decoder.ARSCDecoder.decode(ARSCDecoder.java:49)
... 7 more
這個報錯的錯因是:
使用了新的adt,而反編譯使用的apktool.jar的版本太低了,無法反編譯某些apk,下載新的版本的apktool.jar並替換現在的版本即可。
注:apk的反編譯只可用於學習和研究,堅決不可隨意修改他人程式碼,更加不可用作商用,望慎行!如有惡意行為,後果自負。