逆コンパイルのプロセスは、コンパイルの逆であり、コンパイルされたプログラミング言語をコンパイルされていない状態に戻すこと、つまり、プログラミング言語のソース コードを見つけることです。機械が理解できる言語をプログラマが理解できる言語に変換することです。 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 の主な機能は視覚的な操作を提供することです。ファイルをウィンドウに直接ドラッグ アンド ドロップできます。レンダリングは次のとおりです。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 つ増えていることがわかります。以下:#基本的な設定が完了したら、クラス ファイルのデフォルトの開く方法を設定できます:
Eclipse -> ウィンドウ -> 設定 -> 一般 -> エディター -> ファイルの関連付け クラス ファイルを開くには 2 つの方法があることがわかります。まず、ここで JadClipse と Eclipse に付属のクラス ファイル ビューアーを設定します。 JadClipse がデフォルトです。
すべての設定が完了しました。これで、ソース コードを表示できます。表示したいクラスを選択し、F3 キーを押してソース コードを表示します。JadClipse がデフォルト設定でない場合は、デフォルト設定に設定してください。
詳細 Java の知識をさらに深めたい場合は、
java 基本チュートリアル以上がJavaを逆コンパイルする方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。