android 反編譯和代碼解讀

反編譯工具小米人改之理:  http://www.xiaomiren.net/apkmodifier/

一  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反編譯
image image
將smali文件包刪除.
2 將上一步保存的源碼解壓,在此建立一個src目錄.將源碼放入src下,導入到eclipse中.結構如下.
image image
反編譯完成.錯誤會很多..可以選擇不同的工具來反編譯,然後交叉對比.我一般使用jd-ui和jad-eclipse插件來編譯.

jad-eclipse配置
image
image

二 錯誤代碼還原規則

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結構
 

反編譯代碼
image
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枚舉
image
還原
image

 

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

發佈了12 篇原創文章 · 獲贊 4 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章