
Decompiler da bytecode Java a Java, utilizzato in IntelliJ IDEA.
Fernflower è il primo decompilatore analitico realmente funzionante per Java e probabilmente per un linguaggio di programmazione di alto livello in generale.
Le release sono pubblicate nel Intellij Community repository.
Si prega di inviare segnalazioni di bug e richieste di funzionalità al issue tracker (nel sottosistema Java. Decompiler. Engine).
Fernflower è integrato in IntelliJ IDEA e viene utilizzato principalmente per mostrare codice Java durante il debugging o la navigazione attraverso file class.
Fernflower può essere eseguito da riga di comando in modalità standalone utilizzando il seguente comando:
java -jar fernflower.jar [-<opzione>=<valore>]* [<sorgente>]+ <destinazione>
* significa zero o più volte
+ significa una o più volte
<sorgente>: file o directory contenente file da decompilare.
Le directory vengono scansionate ricorsivamente.
Le estensioni di file consentite sono class, zip e jar.
Le sorgenti con prefisso -e= indicano file "libreria" che non verranno decompilati ma presi in considerazione nell'analisi delle relazioni
tra classi o metodi.
In particolare la rinomina degli identificatori (vedi l'opzione ren) può beneficiare delle informazioni sulle classi esterne.
<destinazione>: directory di destinazione in cui posizionare il codice Java risultante
<opzione>=<valore>: un'opzione da riga di comando con il corrispondente valore (vedi "Opzioni da riga di comando" sotto).
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\
Ad eccezione di mpm e urc, il valore 1 indica che l'opzione è attivata, 0 - disattivata.
Il valore predefinito, se presente, è indicato tra parentesi.
Tipicamente, le seguenti opzioni verranno modificate dall'utente, se del caso: hes, hdc, dgs, mpm, ren, urc Le restanti opzioni possono essere lasciate così come sono: sono destinate a reverse engineer professionisti.
rbr (1): nascondi metodi bridgersy (0): nascondi membri di classe sinteticidin (1): decompila classi internedc4 (1): collassa riferimenti a classi 1.4das (1): decompila asserzionihes (1): nascondi invocazione super vuotahdc (1): nascondi costruttore predefinito vuotodgs (0): decompila firme generichener (1): assumi return che non lancia eccezioniden (1): decompila enumerazionirgn (1): rimuovi invocazione getClass() quando fa parte di un'istruzione new qualificatalit (0): output di valori numerici "così come sono"Alcuni offuscatori assegnano alle classi e ai loro membri nomi brevi, privi di significato e soprattutto ambigui. Ricompilare tale codice porta a un gran numero di conflitti. Pertanto, è consigliabile lasciare che il decompilatore rinomini gli elementi a sua volta, garantendo l'unicità di ogni identificatore.
L'opzione ren (cioè -ren=1) attiva la funzionalità di rinomina. La strategia di rinomina predefinita funziona come segue:
org.jetbrains.java.decompiler.main.extern.IMemberIdentifierRenamer nell'opzione urc
(es. -urc=com.example.MyRenamer) a Fernflower. La classe deve essere disponibile nel classpath dell'applicazione.Il significato di ogni metodo dovrebbe essere chiaro dal nome: toBeRenamed determina se l'elemento verrà rinominato, mentre gli altri tre forniscono nuovi nomi rispettivamente per classi, metodi e campi.
Crea uno script di avvio eseguibile:
./gradlew :installDist
Lo script di avvio viene generato in build/install/engine/bin.
Fernflower fa parte del progetto IntelliJ Community, i contributi sono benvenuti, il modo preferito per inviare patch è creare una pull request nel repository IntelliJ community. Quando si inviano patch, si prega di seguire le linee guida per i contributi.
Fernflower è concesso in licenza secondo i termini della Apache License Version 2.0.
Fernflower è stato originariamente sviluppato da Stiver ma è stato mantenuto da JetBrains dal 2014. Alcune patch da ForgeFlower sono state unite in questo repository. Il mirror di Fernflower è stato anche mantenuto da Andrew McRae per molto tempo.
Il nome corretto è Fernflower, non FernFlower.
asc (0): codifica caratteri non ASCII in stringhe e caratteri letterali come escape Unicodebto (1): interpreta int 1 come booleano true (workaround per un bug del compilatore)nns (0): consenti attributo sintetico non impostato (workaround per un bug del compilatore)uto (1): considera i tipi senza nome come java.lang.Object (workaround per un difetto architetturale del compilatore)udv (1): ricostruisci nomi di variabili da informazioni di debug, se presentiump (1): ricostruisci nomi di parametri da attributi corrispondenti, se presentirer (1): rimuovi intervalli di eccezioni vuotifdi (1): de-inline strutture finallympm (0): tempo massimo di elaborazione consentito per metodo decompilato, in secondi. 0 significa nessun limite superioreren (0): rinomina classi ed elementi di classe ambigui (risp. offuscati)urc (-): nome completo di una classe fornita dall'utente che implementa l'interfaccia IIdentifierRenamer. Viene utilizzata per determinare quali identificatori di classe devono essere rinominati e fornisce nuovi nomi di identificatore (vedi "Rinomina degli identificatori")inn (1): verifica la presenza dell'annotazione @NotNull specifica di IntelliJ IDEA e rimuovi il codice inserito se trovatolac (0): decompila espressioni lambda in classi anonimenls (0): definisci un carattere di nuova riga da utilizzare per l'output. 0 - '\r\n' (Windows), 1 - '\n' (Unix), predefinito dipendente dal sistema operativoind: stringa di indentazione (predefinito 3 spazi)crp (0): usa record patterns dove possibilecps (0): usa switch con patterns dove possibilelog (INFO): livello di logging, valori possibili sono TRACE, INFO, WARN, ERRORiec (0): includi l'intero classpath nel contesto durante la decompilazioneisl (1): inline espressioni lambda sempliciucrc (1): nascondi costruttore e getter di record non necessaricci (1): verifica se la risorsa in try-with-resources implementa effettivamente l'interfaccia AutoCloseablejvn (0): sovrascrivi qualsiasi nome di variabile locale con nomi in stile JADjpr (0): includi nomi di parametri nella denominazione JADpbo (0): aggiungi parentesi chiarificatrici quando operatori bitwise/shift sono misti con operatori aritmetici