
JavaバイトコードからJavaへの逆コンパイラ。IntelliJ IDEAで使用されています。
Fernflowerは、Java向けの最初の実際に動作する解析型逆コンパイラであり、おそらく高水準プログラミング言語全般としても最初のものです。
リリースは、Intellij Communityリポジトリ で公開されています。
バグ報告や機能リクエストは、issue tracker(サブシステムJava. Decompiler. Engine)へお送りください。
FernflowerはIntelliJ IDEAにバンドルされており、主にデバッグ中やクラスファイルを参照する際にJavaコードを表示するために使用されます。
Fernflowerは、以下のコマンドを使用してスタンドアロンモードでコマンドラインから実行できます:
java -jar fernflower.jar [-<option>=<value>]* [<source>]+ <destination>
* は0回以上の繰り返しを意味します
+ は1回以上の繰り返しを意味します
<source>: 逆コンパイルするファイルまたはディレクトリ。ディレクトリは再帰的にスキャンされます。許可されるファイル拡張子は class、zip、jar です。-e= が前置されたソースは「ライブラリ」ファイルを意味し、逆コンパイルはされませんが、クラスやメソッド間の関係を解析する際に考慮されます。特に識別子のリネーム(renオプション参照)は外部クラスの情報から恩恵を受けることができます。
<destination>: 結果のJavaソースを配置する先のディレクトリ
<option>=<value>: 対応する値を持つコマンドラインオプション(以下の「コマンドラインオプション」を参照)。
java -jar fernflower.jar -hes=0 -hdc=0 c:\Temp\binary\ -e=c:\Java\rt.jar c:\Temp\source\
java -jar fernflower.jar -dgs=1 c:\Temp\binary\library.jar c:\Temp\binary\Boot.class c:\Temp\source\
mpmとurcを除き、値1はオプションが有効、0は無効を意味します。デフォルト値(ある場合)は括弧内に示されています。
通常、ユーザーが変更する可能性があるオプションは次のとおりです: hes, hdc, dgs, mpm, ren, urc 残りのオプションはそのままにしておくことができます。これらはプロのリバースエンジニア向けです。
rbr (1): ブリッジメソッドを非表示にするrsy (0): シンセティッククラスメンバーを非表示にするdin (1): 内部クラスを逆コンパイルするdc4 (1): 1.4クラス参照を圧縮するdas (1): アサーションを逆コンパイルするhes (1): 空のスーパー呼び出しを非表示にするhdc (1): 空のデフォルトコンストラクタを非表示にするdgs (0): ジェネリックシグネチャを逆コンパイルするner (1): リターンが例外をスローしないと仮定するden (1): 列挙型を逆コンパイルするrgn (1): 修飾付きnew文の一部である getClass() 呼び出しを削除するlit (0): 数値リテラルを「そのまま」出力するasc (0): 文字列および文字リテラル内の非ASCII文字をUnicodeエスケープとしてエンコードする一部の難読化ツールは、クラスとそのメンバー要素に短く意味のない、とりわけ曖昧な名前を付けます。このようなコードを再コンパイルすると、多数の競合が発生します。したがって、逆コンパイラが要素をリネームして各識別子の一意性を確保することをお勧めします。
renオプション(-ren=1)はリネーム機能を有効にします。デフォルトのリネーム戦略は次のとおりです:
これらのルールは、リネーム中に逆コンパイラによって呼び出される4つの主要メソッドの独自の実装を提供することで上書きできます。urcオプション(例: -urc=com.example.MyRenamer)で org.jetbrains.java.decompiler.main.extern.IMemberIdentifierRenamer を実装するクラスをFernflowerに渡すだけです。このクラスはアプリケーションのクラスパス上で利用可能でなければなりません。
各メソッドの意味は名前から明らかです: toBeRenamedは要素がリネームされるかどうかを決定し、他の3つはそれぞれクラス、メソッド、フィールドの新しい名前を提供します。
実行可能な起動スクリプトをビルドする:
./gradlew :installDist
起動スクリプトは build/install/engine/bin に生成されます。
FernflowerはIntelliJ Communityプロジェクトの一部です。貢献を歓迎します。パッチの送信方法としては、IntelliJ Communityリポジトリでプルリクエストを作成することを推奨します。パッチを提出する際は、コントリビューションガイドラインに従ってください。
FernflowerはApache License Version 2.0の下でライセンスされています。
Fernflowerは当初Stiverによって開発されましたが、2014年以降はJetBrainsによってメンテナンスされています。ForgeFlowerからのいくつかのパッチがこのリポジトリにマージされました。FernflowerのミラーはAndrew McRaeによって長期間メンテナンスされていました。
正しい名称はFernflowerであり、FernFlowerではありません。
bto (1): int 1をboolean trueとして解釈する(コンパイラのバグに対する回避策)nns (0): 設定されていないシンセティック属性を許可する(コンパイラのバグに対する回避策)uto (1): 名前のない型を java.lang.Object とみなす(コンパイラアーキテクチャの欠陥に対する回避策)udv (1): デバッグ情報から変数名を再構築する(存在する場合)ump (1): 対応する属性からパラメータ名を再構築する(存在する場合)rer (1): 空の例外範囲を削除するfdi (1): finally構造をインライン解除するmpm (0): 逆コンパイルされたメソッドあたりの最大処理時間(秒)。0は上限なしを意味するren (0): 曖昧な(難読化された)クラスおよびクラス要素をリネームするurc (-): IIdentifierRenamer インターフェースを実装するユーザー提供クラスの完全名。どのクラス識別子をリネームすべきかを判断し、新しい識別子名を提供するために使用されます(「識別子のリネーム」を参照)inn (1): IntelliJ IDEA固有の@NotNullアノテーションをチェックし、見つかった場合は挿入されたコードを削除するlac (0): ラムダ式を匿名クラスに逆コンパイルするnls (0): 出力に使用する改行文字を定義する。0 - '\r\n' (Windows)、1 - '\n' (Unix)、デフォルトはOS依存ind: インデント文字列(デフォルトは3スペース)crp (0): 可能な場合にレコードパターンを使用するcps (0): 可能な場合にパターンを使用したswitchを使用するlog (INFO): ログレベル。指定可能な値は TRACE, INFO, WARN, ERRORiec (0): 逆コンパイル時にコンテキストにクラスパス全体を含めるisl (1): 単純なラムダ式をインライン化するucrc (1): 不要なレコードコンストラクタとゲッターを非表示にするcci (1): try-with-resources内のリソースが実際に AutoCloseable インターフェースを実装しているかチェックするjvn (0): すべてのローカル変数名をJADスタイルの名前で上書きするjpr (0): JAD命名にパラメータ名を含めるpbo (0): ビット演算子/シフト演算子が算術演算子と混在している場合に明確化する括弧を追加する