一、反編譯工具:
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的反編譯只可用於學習和研究,堅決不可隨意修改他人代碼,更加不可用作商用,望慎行!如有惡意行為,后果自負。