DJ_Java_Decompiler新手入門教程


 首先聲明:這篇文章並不是我原創,只是感覺挺有用處,想跟大家分享一下,所以標注為原創,希望能有更多的朋友可以看到,還請原作者諒解。微笑


 昨天大D說讓我寫下DJ入門的基礎,今天寫了一大半了,結果不小心把瀏覽器給關掉了,傷心死了,本來里面請了點JAVA知道的,但是現在就不講了,下次有時間再講吧,在公司不好弄,今天就只請DJ

話說回來,先看圖

 


其中代碼區是DJ反編譯出來的源碼
方法列表區是在這個類里所有的方法的列表,雙擊后會在代碼區進入該方法的區域,快捷鍵區我們用不着,因為那些是把這個當作IDE才用的着的,比如寫JAVA程序啦

下面我們請下這個怎么用,首先我們用DJ寫段小程序看看
打開記事本,加入以下代碼 
public class b { 
public static void main(String args[]){     
  int i=5,n= Integer.parseInt(args[0]);         //定義整形變量i=5,n=從命令行輸入的參數  
   boolean flag=i>n ? true:false;                                  //定義boolean型變量flag.並用三目運算符計算flag的值,如果i大於n,flag值為true,如果i不大於n,flag值為false 

  System.out.println(flag);                            //輸出flag的值 

}  
保存到D,存為b.java 
打開命令提示符,輸入d: 
javac b.java 
java b 8 
java b 3 
注意:每句都要回車  
運算結果 


b后面的數字是給程序傳數進去,我們的n就是讀的這個參數 
下面我用用DJ反編譯b.class,這個文件和b.java在一個目錄里,當我們用javac b.java時就會生成這個文件,java b全寫應該是java b.class,但是后面的后綴可以省略,前面的.java不能省

UltraEdit-32打開

尷尬不好意思,這個圖片上傳失敗了



看不懂吧,說實話,要是把這個看懂也不難,但如果里面有中文那就難懂了
下面再用我們的DJ打開



代碼反編譯出來后和我們原來的不一樣吧,多了一個public b(),其實這個不是多的,每個類都要有一個和自己類名相同的構造方法,只是我們沒寫而已
下面的main函數里也和我們原來寫的不一樣了
我們原來的int i=5變成了byte byte0 = 5; //其實這個無所謂了,因為每個我們的i值為5,用不着int型的,byte就夠了,這是JAVA給我們優化的
下面n的值在這里變成了i的值,這個都無所謂的,因為JAVA編譯成字節碼后算的是順序,名字無所謂
后面的三目運算符也差不多的.輸出函數都一樣的了.那大家在想了,這樣有什么用呢,我們把他反編譯成了源碼也用不着啊,HALO里根本看不到這樣的東西,全是字節碼

下面說到正題了,DJ,settings-Decompiler settings,在彈出的窗口中選中Generate JVM instructions as comments(annotete),然后點OK,再按F5刷新 
如圖

第句源碼下面的//開頭的都是上面的語句的字節碼.比如 
        byte byte0 = 5; 
    //    0    0:iconst_5        
    //    1    1:istore_1      
源碼是byte byte0=5;       字節碼是 
//0 0:iconst_5; 
//1 1:istore_1; 
大家看到了,這里面都是以0開始計數,但是HALO里是以1開始計數的                           
下圖
                                  
所以大家在刪代碼的時候,如果DJ里是5,那么大HALO里就要5+1=6.切記..... 
大家又想問,iconst_5,istore_1是啥意思呢
iconst_5   將int型5推送至棧頂 
istore_1   將棧頂int型數值存入第二個本地變量(網上都說是第一個) 
不知道為什么是第二個,而不是第一?難道也從0開始,在網上查了下都說是第一個,而我的那個JVM指令集說是第二個,不管這個了,這只是相變量索引值,看下面的代碼還能看到istore_2,istore_3之類的,這些是索引,不是真正的值. 

        boolean flag = byte0 > i; 
    //    7    9:iload_1         
    //    8   10:iload_2         
    //    9   11:icmple          18 
    //   10   14:iconst_1        
    //   11   15:goto            19 
    //   12   18:iconst_0        
    //   13   19:istore_3        
這段是三目運算符的代碼,iload_1,iload_2;是取出istore_1和istore_2索引變量取出,就是上面的那個命令存進去的索引值. 
然后icmple相當於if,他會拿棧頂的兩個值進行比較,就是iload_1,iload_2中的兩個值,如果小於等於0就跳轉,就是goto下面的語句,goto相當於else,這句話的意思就是,拿兩個值比較,如果iload_1中的值大於iload_2的值就往下執行icmple后的語句,然后跳過goto后面的語句,如果小於就跳過下語句,而執行goto下面的語句.大家看到icmple下面的iconst_1了吧,這句就是給int賦值為1,boolean是true,這下大家知道為什么那些XX教程里為什么留兩中都有這句了吧,知道這句goto下面的iconst_0大家應該也猜到是false了吧, 
istore_3是把變量存入第3個變量(icmple和goto各一句,這句不屬於goto,不管icmple和goto執行了哪一個,都會執行這一句,這句是將判斷的值存進棧的).然后下面的 
        System.out.println(flag); 
    //   14   20:getstatic       #3   <Field PrintStream System.out> 
    //   15   23:iload_3         
    //   16   24:invokevirtual   #4   <Method void PrintStream.println(boolean)> 
    //   17   27:return       
是打印語句, 
getstatic   獲取指定類的靜態域,並將其值壓入棧頂 
這句是裝System.out這個靜態方法取出, 
iload_3將剛才存入的那個值取出來,下面的invokevirtual   #4   <Method void PrintStream.println(boolean)>開始輸出指定數據類型的值,return跳出. 

今天就講這么多了,要正式上班了,看我在上班時候寫的份上怎么也要頂下吧. 


JVM字節碼到這里下載,是中文的,方便XX. 
http://bbs.cn456.com/read-htm-tid-52033.html

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM