JD-GUI反編譯後代碼邏輯分析

一,用jd-gui.exe等工具查看源代碼。如何你不會,能夠參看此文章:java

 

http://blog.csdn.net/hp_2008/article/details/8207879ide

 能夠到如下鏈接下載可視化反編譯工具:工具

http://download.csdn.net/detail/hp_2008/5099046ui

二,反編譯後的源代碼,是亂的,看不太懂。這是由於開發者在發佈APK時,通常都會用代碼混淆器將原始的源代碼打亂,
這也是防盜的一種方法。可是再怎樣防,道高一尺,魔高一丈,用反編譯工具很輕鬆的就可反編譯成源碼。要想作到反編譯成一點也看不懂的代碼,這很難,
在Android Java開源的世界裏就更難作到了。固然你能夠把核心的放到中間層,用C/C++封裝成庫,經過JNI調用,這樣要想反編譯庫就有難度了。this

用混淆器打亂的代碼,反編譯後,要想看懂也不是一件容易的事。由於大部人都會用免費的混淆器來混淆源代碼,大部份反編譯過來的代碼就有必定的規則可尋:spa

(本人水平有限,若有什麼不對的地方,還請指教,很是感謝).net

反編譯後的代碼通常會產生如下結構的代碼,(代碼結構是我的總結的,若有雷同,純屬巧合)比較難看懂,本文章根據實現狀況對這幾種結構作個簡單說明。3d

1,反編譯後的代碼:if while結構
    if (BTActivity.access$2300(this.this$0))
    {
      int i = BTActivity.access$700(this.this$0).sendCommand(1028, 4, paramInt);
      BTActivity.access$2500(this.this$0).notifyDataSetChanged();
    }
    while (true)
    {
      return;
      Bluetooth localBt = BTActivity.access$700(this.this$0);
      int k = BTActivity.access$600(this.this$0);
      int l = localBt.sendCommand(1026, paramInt, k);
     }code

 (1)只分析邏輯
  很顯然上面的代碼也不是原始的源代碼,可是很接近了,若是要想完成還原,還得本身改。
 分析上面的代碼:這裏應該有一個if else的邏輯。從上面的代碼分析,return下的代碼
 應該是永遠不會被執行,但這是不可能的。因此上面的代碼邏輯(咱們先不看語句)應該是這樣的,
  去掉while和return,加上else,修改後以下:
     if (BTActivity.access$2300(this.this$0))
    {
       int i = BTActivity.access$700(this.this$0).sendCommand(1028, 4, paramInt);
       BTActivity.access$2500(this.this$0).notifyDataSetChanged();
    }
  else
  {
      Bluetooth localBt = BTActivity.access$700(this.this$0);
      int k = BTActivity.access$600(this.this$0);
      int l = localBt.sendCommand(1026, paramInt, k);
    }
 
 這樣的邏輯纔是做者的本意。對象

  (2)邏輯分析完了,應該分析語句.
      A,這個真的很難看懂。像這句:int i = BTActivity.access$700(this.this$0).sendCommand(1028, 4, paramInt);
      很顯然,這個是引用外部的一個類中的一個方法。而後返回整類,從下面的語句能夠得知,這個返回值是用不到的。因此這句可去掉int i 
      還原上面的語句應該是這樣的:
      BTActivity.access$700(this.this$0).sendCommand(1028, 4, paramInt);
      
      B,access$700是什麼意思呢。這個應該是BTActivity類中的一個對像,而後這個對象有sendCommand方法。這樣你就能夠去查這個BTActivity類定義的哪一個對象
      有這樣一個方法了,這好理解。
      
      很差理解的是這句:int k = BTActivity.access$600(this.this$0); 這句初步還原就是去掉int k。
      而後是這個access$600,它對應的是BTActivity中的哪一個方法呢。這很難肯定,因此我說要猜,那有沒有方法呢。固然有:
      1,看這個類中有多少個方法,若是隻有一個,那指定就是它了。
      2,若是有多個,那就要看參數。若是隻有一個方法的參數與之相對應,那必定是它。
      3,若是參數同樣的也有多個。那看邏輯。若是看不出來,只有猜:)。或參加本身的邏輯。
   
   (3)爲何會出現像access$700(方法不同,後面的數字也不同)這樣的方法名呢,緣由是,調用者和被調者不在同一個類中。內部類也不行,若是
   二者在同一個類中,好比同類的方法調用,那反編譯後的名字必定是可看懂的。不會是有數字的名字。
   
   (4) 再舉一個更簡單的if else例
       反編譯後的代碼:
        if (paramBoolean)
        paramTextView.setTextColor(-16727809);
       while (true)
       {
         return;
         paramTextView.setTextColor(-1315861);
       }
     
       還原成真正的原始代碼,按我上面說的應該是:
       
         if (paramBoolean)
         {
           paramTextView.setTextColor(-16727809);
         }
         else
         {
            paramTextView.setTextColor(-1315861);
         }   
         
         之後碰到這樣的if while還原就應該是上面的樣子。
   

2, 反編譯後的代碼:switch case while結構

    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");
    }
   
   (1)分析邏輯:根據mBand的不一樣值,設置文本的顯示內容。
   
   這個很好看懂,再也不多說,還原成原始代碼:
    switch (mBand)
    {

     case 0:
      mBand.setText("FM1");
      break;
     case 1:
       mBand.setText("FM2");
       break;
     case 2:
       mBand.setText("AM");
       break;
     default:
    }
 
   (2)這裏關鍵的地方是:一個continue對你應着一個case的結束;。

 

3,反編譯後代碼以下:if for while結構 
      int i15 = this.freq;
      int i16 = this.rmin;
      if (i15 < i16)
        i17 = this.min;
      int i29;
      for (this.freq = i17; ; this.freq = i29)
      {
        int i27;
        int i28;
        do
        {
          this.x = getWidth();
          this.y = -1;
          break label32:
          i27 = this.freq;
          i28 = this.max;
        }
        while (i27 <= i28);
        i29 = this.max;
      }
      this.y = 0;
      invalidate();
      
      (1)代碼邏輯分析:保證freq的值在min和max之間。
      
       分析後獲得的原始源代碼:
       
      if (freq < min)
      {
       freq = min;
      }
      
      if (freq <= max)
      {
         x = getWidth();
         y = -1;  
      }
      else
      {
       freq  = max;
       y = 0;
       invalidate();
      }
      
     (2)獲得上面的源代碼關鍵在於,按反編譯後的代碼走一遍。 

 

 4, 解析switch for while結構代碼

 

   PowerManager localPowerManager = (PowerManager)getSystemService("power");
    switch (paramInt)
    {
    default:
    case 0:
    case 1:
    }
    for (String str = "on"; ; str = "other")
      while (true)
      {
        PowerManager.WakeLock localWakeLock = localPowerManager.newWakeLock(6, str);
        localWakeLock.acquire();
        localWakeLock.release();
        return;
        str = "off";
      }

還原原始源代碼:

     PowerManager localPowerManager = (PowerManager)getSystemService("power");
     String str = null;
     switch (paramInt)
     {
      case 0:
       str = "on";
       break;
      case 1:
       str = "off";
       break;
      default:
       str = "other";
       break;
     }

     PowerManager.WakeLock localWakeLock = localPowerManager.newWakeLock(6, str);
        localWakeLock.acquire();
        localWakeLock.release();

 

 

5, 分析返編譯後的代碼(if while結構)

 例1:

   if (paramInt1 == 0)
      this.mMessage.setText("");
    while (true)
    {
      this.mAdditionalMessage.setVisibility(8);
      int i = this.mLevel.getMax();
      if (paramInt2 != i)
        this.mLevel.setMax(paramInt2);
      Toast localToast = this.mToast;
      ...... 

      return;
      TextView localTextView = this.mMessage;
      String str = "" + paramInt1;
      localTextView.setText(str);
    }

  分析:1,先去掉「this"

              2,看返編譯後的按順序邏輯走一遍。能夠看出while到return這段代碼,無論怎麼樣都會執行的。因此原始代碼應該是這樣的:

     setSmallIcon(paramInt1);
     paramInt1 &= 2147483647;
     if (paramInt1 == 0)
     {
       mMessage.setText("");
     }
     else
     {
       String str = "" + paramInt1;
       mMessage.setText(str);
     }
     mAdditionalMessage.setVisibility(8);
     if (paramInt2 != mLevel.getMax())
     {
       mLevel.setMax(paramInt2);
     }
     mToast.setView(mView);

      ......

 

 6,一個continue對應一個back原則(switch while結構)
在這種形式中,一個contiune必定是對應一個back,但一個case不必定只對應一個contiune,也有一個case對應兩個或多個contiune(即back).
如如下反編譯後的代碼:

 

 1 switch (getId())  
 2  {  
 3  case 2131034119:  
 4  case 2131034120:  
 5  case 2131034121:  
 6  case 2131034122:  
 7  case 2131034123:  
 8  case 2131034124:  
 9  case 2131034125:  
10  case 2131034126:  
11  case 2131034127:  
12  case 2131034128:  
13  default:  
14  case 2131034129:  
15  case 2131034130:  
16  case 2131034131:  
17  case 2131034132:  
18  case 2131034133:  
19  case 2131034134:  
20  case 2131034117:  
21  case 2131034118:  
22  }  
23  while (true)  
24  {  
25    return;  
26    int i = paramVerticalSeekBar.getProgress() * 14;  
27    int j = paramVerticalSeekBar.getMax();  
28    int k = i / j;  
29    if (APPActivity.access$200(this.this$0) == k)  
30      continue;  
31    int l = APPActivity.access$202(this.this$0, k);  
32    int i1 = APPActivity.access$200(this.this$0);  
33     continue;  
34    int i3 = paramVerticalSeekBar.getProgress() * 14;  
35    int i4 = paramVerticalSeekBar.getMax();  
36    k = i3 / i4;  
37    if (APPActivity.access$400(this.this$0) == k)  
38      continue;  
39    int i5 = APPActivity.access$402(this.this$0, k);  
40    EQ localEQ2 = APPActivity.access$1400(this.this$0);  
41    int i6 = APPActivity.access$400(this.this$0);  
42    int i7 = localEQ2.sendCommand(257, 2, i6);  
43    continue;  
44    int i8 = paramVerticalSeekBar.getProgress() * 14;  
45    int i9 = paramVerticalSeekBar.getMax();  
46    k = i8 / i9;  
47    if (APPActivity.access$500(this.this$0) == k)  
48      continue;  
49    int i10 = APPActivity.access$502(this.this$0, k);  
50    int i11 = APPActivity.access$500(this.this$0);  
51    continue;  
52    int i13 = paramVerticalSeekBar.getProgress() * 3;  
53    int i14 = paramVerticalSeekBar.getMax();  
54    k = i13 / i14;  
55    if (APPActivity.access$600(this.this$0) == k)  
56      continue;  
57    int i15 = APPActivity.access$602(this.this$0, k);  
58    EQ localEQ4 = APPActivity.access$1400(this.this$0);  
59    int i16 = APPActivity.access$600(this.this$0);  
60    int i17 = localEQ4.sendCommand(257, 8, i16);  
61    continue;  
62    int i18 = paramVerticalSeekBar.getProgress() * 3;  
63    int i19 = paramVerticalSeekBar.getMax();  
64    k = i18 / i19;  
65    if (EQActivity.access$700(this.this$0) == k)  
66      continue;  
67    int i20 = APPActivity.access$702(this.this$0, k);  
68    EQ localEQ5 = APPActivity.access$1400(this.this$0);  
69    int i21 = APPActivity.access$700(this.this$0);  
70    continue;  
71    int i23 = paramVerticalSeekBar.getProgress() * 3;  
72    int i24 = paramVerticalSeekBar.getMax();  
73    k = i23 / i24;  
74    if (APPActivity.access$800(this.this$0) == k)  
75      continue;  
76    int i25 = APPActivity.access$802(this.this$0, k);  
77    EQ localEQ6 = APPActivity.access$1400(this.this$0);  
78    int i26 = APPActivity.access$800(this.this$0);  
79    continue;  
80    int i28 = paramVerticalSeekBar.getProgress() * 14;  
81    int i29 = paramVerticalSeekBar.getMax();  
82    k = i28 / i29;  
83    if (APPActivity.access$900(this.this$0) == k)  
84      continue;  
85    int i30 = APPActivity.access$902(this.this$0, k);  
86    EQ localEQ7 = APPActivity.access$1400(this.this$0);  
87    int i31 = APPActivityvity.access$900(this.this$0);  
88    continue;  
89    int i33 = paramVerticalSeekBar.getProgress() * 3;  
90    int i34 = paramVerticalSeekBar.getMax();  
91    k = i33 / i34;  
92    if (APPActivity.access$1000(this.this$0) == k)  
93      continue;  
94    int i35 = APPActivity.access$1002(this.this$0, k);  
95    EQ localEQ8 = APPActivity.access$1400(this.this$0);  
96    int i36 = APPActivity.access$1000(this.this$0);  
97  }  
View Code

 


    分析代碼:

1),上遍已對這種形式有講過,一個continue對應一個case,可是你數一數會發現,對不上號,明顯case多於contiune,緣由是什麼呢?其實switch裏的default對應的是while中的return,在switch中default以上的case是用不着,是沒有用的。

2),若是default上面的case沒有用,聰明的你能夠可能會問兩個問題?A,default上面的case沒有用,爲何還會有呢?緣由很簡單,由於反編譯器也不是全智能的總會有不對的(可是執行邏輯是不會有錯),呵呵真正的緣由固然不會是這樣,你能夠本身去分析一下,從整個程序分析就能夠得出結論來。B,那按一個continue對應一個back的原則不是有錯嗎? 固然沒有。一個continue仍是對應一個back, 聰明的你必定看懂了,每兩個continue中間還有一個if語句,對,沒錯,你理解是對的,就是在這中間知足條件時就會back,因此就會有一個continue與之相對應。  所這裏每一個if + continue + continue的形式對應一個case。3),恢復原代碼結構就變的簡單,這裏就再敖敘了

相關文章
相關標籤/搜索