首頁 Java Java基礎 java如何進行反編譯

java如何進行反編譯

Dec 07, 2019 pm 03:06 PM
java

java如何進行反編譯

反編譯的過程與編譯剛好相反,就是將已編譯好的程式語言還原到未編譯的狀態,也就是找出程式語言的原始碼。就是將機器看得懂的語言轉換成程式設計師可以看得懂的語言。 Java語言中的反編譯一般指將class檔案轉換成java檔。

Java常用反編譯工具

本文主要介紹4個Java的反編譯工具:javap、jad和cfr以及視覺化反編譯工具JD-GUI

#JAVAP

javap是jdk自帶的工具,可以對程式碼反編譯,也可以查看java編譯器產生的字節碼。 javap和其他兩個反編譯工具最大的差別在於他產生的文件並不是java文件,也不像其他兩個工具產生程式碼那麼容易理解。拿一段簡單的程式碼舉例,如我們想分析Java 7中的switch是如何支援String的,我們先有以下可以編譯通過的原始碼:

public class switchDemoString {
    public static void main(String[] args) {
        String str = "world";
        switch (str) {
            case "hello":
                System.out.println("hello");
                break;
            case "world":
                System.out.println("world");
                break;
            default:
                break;
        }
    }
}
登入後複製

執行以下兩個指令:

javac Decompilation.java
javap -c Decompilation.class
登入後複製

生成程式碼如下:

Compiled from "Decompilation.java"
public class Decompilation {
  public Decompilation();
    Code:
       0: aload_0
       1: invokespecial #8                  // Method java/lang/Object."<init>":()V
       4: return

  public static void main(java.lang.String[]);
    Code:
       0: ldc           #16                 // String world
       2: astore_1
       3: aload_1
       4: dup
       5: astore_2
       6: invokevirtual #18                 // Method java/lang/String.hashCode:()I
       9: lookupswitch  { // 2
              99162322: 36
             113318802: 48
               default: 82
          }
      36: aload_2
      37: ldc           #24                 // String hello
      39: invokevirtual #26                 // Method java/lang/String.equals:(Ljava/lang/Object;)Z
      42: ifne          60
      45: goto          82
      48: aload_2
      49: ldc           #16                 // String world
      51: invokevirtual #26                 // Method java/lang/String.equals:(Ljava/lang/Object;)Z
      54: ifne          71
      57: goto          82
      60: getstatic     #30                 // Field java/lang/System.out:Ljava/io/PrintStream;
      63: ldc           #24                 // String hello
      65: invokevirtual #36                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
      68: goto          82
      71: getstatic     #30                 // Field java/lang/System.out:Ljava/io/PrintStream;
      74: ldc           #16                 // String world
      76: invokevirtual #36                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
      79: goto          82
      82: return
}
登入後複製

javap並沒有將字節碼反編譯成java文件,而是產生了一種我們可以看得懂字節碼。其實javap產生的檔案還是字節碼,只是程式設計師可以稍微看得懂一些。如果你對字節碼有所掌握,還是可以看得懂以上的程式碼的。其實就是把String轉成hashcode,然後再比較。

JAD

JAD是比較不錯的反編譯工具,只要下載執行工具,就可以實現對class檔案的反編譯了。還是上面的原始程式碼,使用jad反編譯後內容如下:

指令:jad.exe Decompilation.class 會產生一個Decompilation.jad的檔案

JAD反編譯的結果如下:

// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov.
// Jad home page: http://www.kpdus.com/jad.html
// Decompiler options: packimports(3) 
// Source File Name:   Decompilation.java

package com.yveshe;

import java.io.PrintStream;

public class Decompilation
{

    public Decompilation()
    {
    }

    public static void main(String args[])
    {
        String str = "world";
        String s;
        switch((s = str).hashCode())
        {
        default:
            break;

        case 99162322: 
            if(s.equals("hello"))
                System.out.println("hello");
            break;

        case 113318802: 
            if(s.equals("world"))
                System.out.println("world");
            break;
        }
    }
}
登入後複製

看上面的程式碼這不就是標準的java的原始碼麼。這個就很清楚的可以看到原來字串的switch是透過equals()和hashCode()方法來實現的。

CFR

JAD很好用,但無奈的是很久沒更新了,所以只能用一款新的工具取代他,CFR是一個不錯的選擇,比起JAD來說,他的語法可能會稍微複雜一些,但是好在他可以用.

CFR將反編譯現代Java特性–Java 8 lambdas(Java和更早版本中的Java beta 103),已經反編譯Java 7 String,但CFR是完全用Java 6寫的.

建議大家手動透過javac Decompilation.java指令來編譯產生Decompilation.class檔,再做測試.

成功的反編譯結果如下:

/*
 * Decompiled with CFR 0_125.
 */
package com.yveshe;

import java.io.PrintStream;

public class Decompilation {
    public static void main(String[] args) {
        String str;
        String s = str = "world";
        switch (s.hashCode()) {
            default: {
                break;
            }
            case 99162322: {
                if (!s.equals("hello")) break;
                System.out.println("hello");
                break;
            }
            case 113318802: {
                if (!s.equals("world")) break;
                System.out.println("world");
            }
        }
    }
}
登入後複製
登入後複製

比較Jad來說,CFR有很多參數,還是剛剛的程式碼,如果我們使用以下指令,輸出結果就會不同:
E :\CRF>java -jar cfr_0_125.jar Decompilation.class

/*
 * Decompiled with CFR 0_125.
 */
package com.yveshe;

import java.io.PrintStream;

public class Decompilation {
    public static void main(String[] args) {
        String str;
        String s = str = "world";
        switch (s.hashCode()) {
            default: {
                break;
            }
            case 99162322: {
                if (!s.equals("hello")) break;
                System.out.println("hello");
                break;
            }
            case 113318802: {
                if (!s.equals("world")) break;
                System.out.println("world");
            }
        }
    }
}
登入後複製
登入後複製

--decodestringswitch表示對於switch支援string的細節進行解碼。

類似的還有--decodeenumswitch、--decodefinally、--decodelambdas等。

--decodelambdas可以對lambda表達式進行反編譯。

JD-GUI

JD-GUI 是一個用C 開發的Java反編譯工具,由Pavel Kouznetsov開發,支援Windows、Linux和蘋果Mac Os三個平台。而且提供了Eclipse平台下的插件JD-Eclipse。 JD-GUI 是基於GPLv3開源協議,對個人使用是完全免費的。 JD-GUI主要的是提供了視覺化操作,直接拖曳檔案到視窗既可,效果圖如下

java如何進行反編譯

JadClipse

java如何進行反編譯

java如何進行反編譯

# #在Eclipse中安裝Jad插件,注意這裡是安裝的是Jad插件不是Jd插件~

所需要資源: net.sf.jadclipse_3.3.0.jar插件jar和JAD.exe反編譯軟體(在文末有下載地址)JadClipse下載地址在官網下載插件的jar包,然後將jar包放到eclipse的plugins目錄下;在打開Eclipse,Eclipse->Window->Preferences-> Java,此時你會發現會比原來多了一個JadClipse的選項如下圖配置JadClipse:

##################基本配置完畢後,我們可以設定一下class檔案的預設開啟方式:######Eclipse->Window->Preferences->General->Editors->File Associations 我們可以看到class檔案的開啟方式有兩個,這裡設定JadClipse和Eclipse自帶的Class File Viewer,而JadClipse是預設的。 ######全部配置完成,下面我們可以查看源碼了,選擇需要查看的類,按F3即可查看源碼.如果JadClipse不是默認設置,設置成默認設置既可.######更多java知識請關注###java基礎教學###欄。 ######

以上是java如何進行反編譯的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
4 週前 By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解鎖Myrise中的所有內容
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

Java 中的完美數 Java 中的完美數 Aug 30, 2024 pm 04:28 PM

Java 完美數指南。這裡我們討論定義,如何在 Java 中檢查完美數?

Java 中的隨機數產生器 Java 中的隨機數產生器 Aug 30, 2024 pm 04:27 PM

Java 隨機數產生器指南。在這裡,我們透過範例討論 Java 中的函數,並透過範例討論兩個不同的生成器。

Java中的Weka Java中的Weka Aug 30, 2024 pm 04:28 PM

Java 版 Weka 指南。這裡我們透過範例討論簡介、如何使用 weka java、平台類型和優點。

Java 中的史密斯數 Java 中的史密斯數 Aug 30, 2024 pm 04:28 PM

Java 史密斯數指南。這裡我們討論定義,如何在Java中檢查史密斯號?帶有程式碼實現的範例。

Java Spring 面試題 Java Spring 面試題 Aug 30, 2024 pm 04:29 PM

在本文中,我們保留了最常被問到的 Java Spring 面試問題及其詳細答案。這樣你就可以順利通過面試。

突破或從Java 8流返回? 突破或從Java 8流返回? Feb 07, 2025 pm 12:09 PM

Java 8引入了Stream API,提供了一種強大且表達力豐富的處理數據集合的方式。然而,使用Stream時,一個常見問題是:如何從forEach操作中中斷或返回? 傳統循環允許提前中斷或返回,但Stream的forEach方法並不直接支持這種方式。本文將解釋原因,並探討在Stream處理系統中實現提前終止的替代方法。 延伸閱讀: Java Stream API改進 理解Stream forEach forEach方法是一個終端操作,它對Stream中的每個元素執行一個操作。它的設計意圖是處

Java 中的時間戳至今 Java 中的時間戳至今 Aug 30, 2024 pm 04:28 PM

Java 中的時間戳記到日期指南。這裡我們也結合範例討論了介紹以及如何在java中將時間戳記轉換為日期。

創造未來:零基礎的 Java 編程 創造未來:零基礎的 Java 編程 Oct 13, 2024 pm 01:32 PM

Java是熱門程式語言,適合初學者和經驗豐富的開發者學習。本教學從基礎概念出發,逐步深入解說進階主題。安裝Java開發工具包後,可透過建立簡單的「Hello,World!」程式來實踐程式設計。理解程式碼後,使用命令提示字元編譯並執行程序,控制台上將輸出「Hello,World!」。學習Java開啟了程式設計之旅,隨著掌握程度加深,可創建更複雜的應用程式。

See all articles