Javaの特性であるプロセス独立言語は逆コンパイルが可能な構造を持つようになります。Javaはコンパイラを介して.javaファイルをバイトコードでコンパイルされた.classファイルにしますが、逆コンパイルを続行すると、.classファイルを.javaファイルに戻すことができます。
これはC#でも可能ですが、C#の逆コンパイルツールはあまりにもうまく作られていて、自分で作ったコードを再逆コンパイルするとよりきれいになったコードが返されることもありました。
ソースが公開される可能性があるため、以前は難読化プログラムを使用して逆コンパイルされたソースを理解するのが難しくなりました。最近では、オープンソースに進むことも多くなり、ビジネスがより複雑になり、高速化するにつれて、難読化の要求はますます減少する傾向があります。
WhaTap Labsの場合も、コードではなくコードを書いた開発者の重要度を高く見ており、コードが公開されることには大きな意味を置いていないので難読化に 気にしません。 実際、WhaTap Labsにはパフォーマンス分析エージェントコードを公開する計画もあります。
それでは、Java decompileについて学びましょう。
逆コンパイルは他のコードを見たいときに使います。磁気コードを逆コンパイルする必要はありません。
たとえば、上記のようなコードでふと Printというクラスがどのように動作するのか疑問に思うかもしれません。Eclipseの場合はF3を押してコードを確認するか、IntelliJの場合はcommand + b(ctrl + b windowの場合)で確認を試すことができます。本人が作成したclass(.javaファイル)ならすぐに関数の宣言部分につながりますが、そうでない場合は次のような画面が出ます。
“source not found” ソースが見つからないという文とともに、そのクラスの Byte code が表示されます。
Byte codeの理解度が高くない以上、何の内容なのか理解しにくいです。(低コードを理解しようとすると精神的健康に有害である可能性があります。)
このような場合、.classファイルをJD-GUIに逆コンパイルすると、.javaコードが表示されます。
Print class の print 関数は “Helloworld” とともに現在時刻を出力するように作成されていることを確認できます。
ここでSystem.out.printlnが気になる場合は? もっと入りながら逆コンパイルをしてみるとわかります。
JD-GUIは、最も一般的なJava逆コンパイルツールです。特にGUIツールを提供して人気があります。JD-GUIは、Windows、Linux、OSXですべて使用できます。
主な特長
いくつかの制限があります。
See the ホームページで確認できます。
それでは、JARファイルを開いてみましょう。
OSXで実行した様子です。jar に含まれる class がパッケージごとに逆コンパイルされて見えることを確認できます。下線付きのクラスの場合、クリックすると、そのクラスの逆コンパイルされたJavaソースに移動します。(jar内の逆コンパイルされたクラスの間でのみ可能です。)
JD-GUIは、逆コンパイルされたjavaコードからフィルタリングされた検索をサポートしています。
難読化を行ったjarファイルを逆コンパイルするとどうなりますか?
逆コンパイルは可能ですが、難読化プロセスを経たため、コードを読むのは難しいです。
難読化されたソースは、すべての変数とクラスが意味のない文字列に置き換えられるため、a、b、c、d… 同じアルファベットクラスファイルが一覧表示されます。関数名もa、b、c、d… で出てきます。(筆者は何度も難読化されたコードを理解するために挑戦しましたが、これも精神的健康に有害です。)
上記コードは2018年度国際難読化大会(IOCCC)出品作です。コンパイル可能な実際に動作するコードです。ホームページに入ると毎年出品されたコードを見ることができます。
逆コンパイルしたソースをコンパイルする場合は、ライブラリ参照をよく見てください。そのクラスをjavaに100%復元したとしても、コンパイル時に参照したライブラリのようにコンパイルしなければエラーが発生しません。
JD-GUIは、GUIをサポートし、スタンドアローンプログラムとして楽に使用できるという利点を持っています。しかし、開発中に逆コンパイルが必要な場合は、プラグインを使用する方が良いでしょう。最後に、逆コンパイルツールを使用してプログラムの動作原理と構造を把握し、それによってよりクールなコードを作成できますが、逆コンパイルツールを使用して他の開発者のコードを乱用しるのはお控えください。