一 apk反編譯
將apk文件解壓後有兩部分文件需要處理,一種是xml文件,另一種一個dex文件(.dex)
1.對xml文件進行包的解析,一般有兩種方式:apktool(推薦)和AXMLPrinter2.jar;
2.從dex到class公認dex2jar.bat,實現反編譯;公認的強者;
3.而class到java的方式要更多樣化一些,因爲只是查看反編譯後的代碼:jd-gui(推薦),Jodeclipse(Jode的Eclipse插件),JadClipse(Jad的Eclipse插件)。
dex解包
1.首先把apk文件改名爲.zip,然後解壓縮其中的class.dex文件,它就是java文件編譯再通過dx工具打包成的。
2.把class.dex拷貝到dex2jar.bat所在目錄。運行dex2jar.bat class.dex,生成classes.dex.dex2jar.jar。
3.運行JD-GUI工具(綠色軟件,好用的軟件!),打開上面的jar文件,即可看到java源代碼。
4 file-saveall將java源碼保存爲zip文件
資源文件解包
1 安裝apktool,將apk反編譯
將smali文件包刪除.
2 將上一步保存的源碼解壓,在此建立一個src目錄.將源碼放入src下,導入到eclipse中.結構如下.
反編譯完成.錯誤會很多..可以選擇不同的工具來反編譯,然後交叉對比.我一般使用jd-ui和jad-eclipse插件來編譯.
二 錯誤代碼還原規則
if…else 語句:
反編譯代碼
if (paramBoolean) paramTextView.setTextColor(-16727809); while (true) { return; paramTextView.setTextColor(-1315861); }
還原後
if (paramBoolean) { paramTextView.setTextColor(-16727809); } else { paramTextView.setTextColor(-1315861); }
會把if ..esle 反編譯成 if …while(true)結構.
反編譯代碼
if (paramInt1 != 1) break label185; if (this.countChild_1 == null) { this.countChild_1 = new PokerCountChild(this.mContext); this.countChild_1 = new PokerCountChild(this.mContext); this.countChild_1.setPosition((int)(0.83D * BaseGameActivity.screenWidth
- this.countChild_1.getWidth()), (int)(0.2D * BaseGameActivity.screenHeight)); this.countChild_1.setCount(paramInt2); addOneChild(this.countChild_1); if (paramInt2 == 0) this.countChild_1.setAlpha(0); } this.countChild_1.setCount(paramInt2); } label185: do return; while (paramInt1 != 2); if (this.countChild_2 == null) { this.countChild_2 = new PokerCountChild(this.mContext); this.countChild_2 = new PokerCountChild(this.mContext); this.countChild_2.setPosition((int)(0.17D * BaseGameActivity.screenWidth),
(int)(0.2D * BaseGameActivity.screenHeight)); this.countChild_2.setCount(paramInt2); addOneChild(this.countChild_2); if (paramInt2 == 0) this.countChild_2.setAlpha(0); } this.countChild_2.setCount(paramInt2);
還原
if(i == 1) { if(countChild_1 == null) { countChild_1 = new PokerCountChild(mContext); countChild_1 = new PokerCountChild(mContext); countChild_1.setPosition((int)(0.83D *
(double)BaseGameActivity.screenWidth - (double)countChild_1.getWidth()),
(int)(0.2D * (double)BaseGameActivity.screenHeight)); countChild_1.setCount(j); addOneChild(countChild_1); if(j == 0) countChild_1.setAlpha(0); } countChild_1.setCount(j); } else if(i == 2) { if(countChild_2 == null) { countChild_2 = new PokerCountChild(mContext); countChild_2 = new PokerCountChild(mContext); countChild_2.setPosition((int)(0.17D *
(double)BaseGameActivity.screenWidth), (int)(0.2D *
(double)BaseGameActivity.screenHeight)); countChild_2.setCount(j); addOneChild(countChild_2); if(j == 0) countChild_2.setAlpha(0); } countChild_2.setCount(j); return; } 會將語句倒序,出現break label結構
反編譯代碼
jd-gui有時會將whilei語句翻譯成if,此處要將if改成while
switch語句
反編譯代碼
switch (this.mBand) { default: case 0: case 1: case 2: } while (true) { return; this.mBand.setText("FM1"); continue; this.mBand.setText("FM2"); continue; this.mBand.setText("AM"); } 還原
switch (mBand) { case 0: mBand.setText("FM1"); break; case 1: mBand.setText("FM2"); break; case 2: mBand.setText("AM"); break; default: }
switch規則就是一個continue對應一個case.要注意是是要外層的continue纔算數,在if裏的continue不算
enum枚舉
還原
jd-gui
http://www.qiaodiqiu.com/how-to-read-java-confusion-after-the-anti-compiled-code.html
http://blog.csdn.net/xyz_fly/article/details/8014455
http://blog.csdn.net/hp_2008/article/details/8626010
jad
http://blog.csdn.net/z3h/article/details/2515287
http://blog.csdn.net/z3h/article/details/2640522