1. 程式人生 > >反編譯相關工具

反編譯相關工具

  dex2jar 下載地址,百度下載(http://code.google.com/p/dex2jar/downloads/list)
  
  APK tool,百度下載(https://bitbucket.org/iBotPeaches/apktool/downloads/ ,https://ibotpeaches.github.io/Apktool/install/  )




  jd gui

  http://code.google.com/p/innlab/downloads/list   
  http://java.decompiler.free.fr/?q=jdgui




  jadx    (用法:https://segmentfault.com/a/1190000012180752#articleHeader7)
  (下載地址: https://github.com/skylot/jadx/tags )




直接執行bin目錄中的jadx-gui.bat,選擇apk檔案即可。


有些apk的體積比較大的時候,反編譯的時候會卡住或者假死。 
解決方案: 
使用記事本或者notpad++開啟jadx-gui.bat 
更改應用執行記憶體 
變更前: 
set DEFAULT_JVM_OPTS= 
變更後: 
set DEFAULT_JVM_OPTS=-Xmx1024M


請注意這裡面有個減號”-“


例如:編譯新版本的微信的時候,建議將該值更改為5GB,也就是-Xmx5120M 
請根據自己電腦的實際配置進行變更


   

Android 反編譯資料整理    http://rayleeya.iteye.com/blog/841076


Android反編譯後代碼閱讀  https://www.cnblogs.com/zjzyh/p/6601204.html




android 反編譯 程式碼 和原始碼對應關係  http://www.codes51.com/itwd/748452.html


用JD-GUI反編譯出來的Andorid程式碼,裡面指向的xml都是數字了



SetContectView(2130903066)
這個2130903066這個View是指向的哪個XML
在JD-GUI哪裡能夠找到,我每個類都看遍了
感覺他這裡指向的數字是相應的資源地址
但是我怎麼看XML對應成哪些資源地址

解決方案
2130903066的十六進位制是7F03001A,在res/values/public.xml裡搜尋7F03001A就知道對應的哪個id了



Android應用逆向——分析反編譯程式碼之大神器   https://blog.csdn.net/charlessimonyi/article/details/52027563


關於apk的反編譯修改,你不知道的事,尤其是官方Rom  https://blog.csdn.net/bingo1991/article/details/7768889




一、 獲取apk資源




   先cd 到 apktool.bat 的資料夾下面


   apktool.bat   d  -f    [apk檔案 ]  -o [輸出資料夾]


   例子: java -jar apktool.jar d -f  SetupWizard.apk  -o setup 


   反編譯出來的資源隨後會在  setup 資料夾下


   


二、 獲取apk程式碼 


  (1) 將 apk 變成 zip 取出其中的  class.dex


  (2) 想要檢視的話 用,首先將 class.dex 放到,dex2jar 工具的目錄下


      執行   dex2jar.bat  classes.dex   
      
      或者   d2j-dex2jar.bat   classes.dex 


      (主要還是看你的下面有哪個)


      然後生成 classes_dex2jar.jar


  (3) 然後用工具  jd-gui.exe     開啟 jar 檔案檢視


  (4) 程式碼中的id 對應 public.xml     10進位制在計算器中轉換到 16進位制,public.xml查詢
      




三、 baksmali

   (1) 如果需要修改的話 用  baksmali 執行,將 classes.dex  轉化變成 smail檔案, 

   java -jar baksmali-1.4.2.jar -o classout/ classes.dex

   會生成  out目錄,裡面是  smail檔案


   (2) 修改後重新打包 out 成   classes.dex


    java -jar smali-1.4.2.jar -o classes.dex classout



四、問題:


1、 反編譯出來的類,用 jd-gui檢視,有些檔案顯示INTERNAL ERROR 解決辦法(http://www.cnblogs.com/langtianya/p/5140226.html)


下載其他的程式碼檢視工具,如:


https://github.com/deathmarine/Luyten


https://github.com/skylot/jadx


(1) 儲存反編譯出來的程式碼----> 檔案


   把需要反編譯的檔案用JD-GUI開啟點選->File->Save JAR soureces
   選擇後匯出一個zip壓縮包!裡面就是所有的原始碼了


java -jar  xxx.exe   執行 




2、Android:逆向工程之資源ID還原小工具 https://blog.csdn.net/annkie/article/details/7790026

五、 錯誤程式碼還原規則

反編譯中顏色值      -16777216  ---- 對應的是 Color裡面的  

System.out.println(String.format("%08x",-16777216));

android的顏色值16進位制範圍是00000000-ffffffff

int

BLACK

-16777216

0xff000000

int

BLUE

-16776961

0xff0000ff

int

CYAN

-16711681

0xff00ffff

int

DKGRAY

-12303292

0xff444444

int

GRAY

-7829368

0xff888888

int

GREEN

-16711936

0xff00ff00

int

LTGRAY

-3355444

0xffcccccc

int

MAGENTA

-65281

0xffff00ff

int

RED

-65536

0xffff0000

int

TRANSPARENT

0

0x00000000

int

WHITE

-1

0xffffffff

int

YELLOW

-256

0xffffff00

(1)if…else 語句: 會把if ..esle 反編譯成 if …while(true)結構.

  反編譯程式碼
if (paramBoolean)
       paramTextView.setTextColor(-16727809);
       while (true)
       {
         return;
         paramTextView.setTextColor(-1315861);
       }

 還原後

      if (paramBoolean)
         {
           paramTextView.setTextColor(-16727809);
         }
         else
         {
            paramTextView.setTextColor(-1315861);
         }  
 
(2) 會將語句倒序,出現break label結構

反編譯程式碼
 

 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)  ----------------------return  while 替換成 else if
            {
                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;
            }


(3) 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:
    }
  
(4)
if(rt != 0)
            break MISSING_BLOCK_LABEL_369;/////為什麼這裡會有這段東西的~?
        filepath = fc.getSelectedFile();

	替換成  return