Javaを逆コンパイルする方法

リリース: 2019-12-07 15:06:07
オリジナル
8853 人が閲覧しました

Javaを逆コンパイルする方法

逆コンパイルのプロセスは、コンパイルの逆であり、コンパイルされたプログラミング言語をコンパイルされていない状態に戻すこと、つまり、プログラミング言語のソース コードを見つけることです。機械が理解できる言語をプログラマが理解できる言語に変換することです。 Java 言語における逆コンパイルとは、一般的にクラス ファイルを Java ファイルに変換することを指します。

一般的に使用される Java 逆コンパイル ツール

この記事では、主に 4 つの Java 逆コンパイル ツール (javap、jad、cfr) とビジュアル逆コンパイル ツール JD-GUI を紹介します。

JAVAP

javap は jdk に付属するツールで、コードを逆コンパイルし、Java コンパイラによって生成されたバイトコードを表示できます。 javap と他の 2 つの逆コンパイル ツールの最大の違いは、javap が生成するファイルが Java ファイルではなく、他の 2 つのツールで生成されるコードほど理解しにくいことです。単純なコードを例に挙げると、Java 7 のスイッチが 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;
        }
    }
}
ログイン後にコピー

次の 2 つのコマンドを実行します。

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 によって生成されたファイルは依然としてバイトコードですが、プログラマはそれをもう少し理解できるようになります。バイトコードについてある程度の知識がある場合でも、上記のコードを理解できます。実際には、文字列をハッシュコードに変換して比較します。

JAD

JADは比較的優れた逆コンパイルツールで、実行ツールをダウンロードすればクラスファイルを逆コンパイルすることができます。上記のソース コードのままで、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 ソース コードではないでしょうか?これは、元の文字列スイッチが、equals() メソッドと hashCode() メソッドを通じて実装されていることを明確に示しています。

CFR

JAD は非常に便利ですが、残念ながら長い間更新されていないため、新しいツールを使用して置き換えるしかありません。CFR はJAD と比較すると、構文が若干複雑になる可能性がありますが、幸いにも .

CFR を使用できます。これは、最新の Java 機能である Java 8 ラムダ (Java および以前のバージョンのベータ 103 の Java) を逆コンパイルします。 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");
            }
        }
    }
}
ログイン後にコピー
ログイン後にコピー

CFR は Jad に比べてパラメータが多く、まだ先ほどのコードですが、次のコマンドを使用すると出力結果が異なります:

E :\CRF>java -jar cfra_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 は、スイッチ サポート文字列の詳細をデコードすることを意味します。

同様のものには、--decodeenumswitch、--decodefinally、--decodelambdas などがあります。

--decodelambdas はラムダ式を逆コンパイルできます。

JD-GUI

JD-GUI は、C で開発された Java 逆コンパイル ツールです。Pavel Kouznetsov によって開発され、Windows、Linux、および Apple Mac OS プラットフォームをサポートしています。 。また、Eclipse プラットフォームでプラグイン JD-Eclipse を提供します。 JD-GUI は GPLv3 オープン ソース ライセンスに基づいており、個人使用の場合は完全に無料です。 JD-GUI の主な機能は視覚的な操作を提供することです。ファイルをウィンドウに直接ドラッグ アンド ドロップできます。レンダリングは次のとおりです。

Javaを逆コンパイルする方法

JadClipse

Jad プラグインを Eclipse にインストールします。Jd プラグインではなく、Jad プラグインがここにインストールされることに注意してください~

必要なリソース: net.sf.jadclipse_3.3.0 .jar プラグイン jar と JAD.exe 逆コンパイル ソフトウェア (記事の最後にダウンロード アドレスがあります)

JadClipse ダウンロード アドレス 公式 Web サイトからプラグインの jar パッケージをダウンロードし、次に、jar パッケージを Eclipse の plugins ディレクトリに配置します。Eclipse、Eclipse->Window->Preferences->Java を開きます。この時点で、図のように JadClipse を設定するための JadClipse オプションが前よりも 1 つ増えていることがわかります。以下:

Javaを逆コンパイルする方法

Javaを逆コンパイルする方法#基本的な設定が完了したら、クラス ファイルのデフォルトの開く方法を設定できます:

Eclipse -> ウィンドウ -> 設定 -> 一般 -> エディター -> ファイルの関連付け クラス ファイルを開くには 2 つの方法があることがわかります。まず、ここで JadClipse と Eclipse に付属のクラス ファイル ビューアーを設定します。 JadClipse がデフォルトです。

すべての設定が完了しました。これで、ソース コードを表示できます。表示したいクラスを選択し、F3 キーを押してソース コードを表示します。JadClipse がデフォルト設定でない場合は、デフォルト設定に設定してください。

詳細 Java の知識をさらに深めたい場合は、

java 基本チュートリアル

列に注目してください。

以上がJavaを逆コンパイルする方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート