
Décompilateur de bytecode Java vers Java, utilisé dans IntelliJ IDEA.
Fernflower est le premier décompilateur analytique réellement fonctionnel pour Java et probablement pour un langage de programmation de haut niveau en général.
Les versions sont publiées dans le dépôt de la communauté IntelliJ.
Veuillez envoyer vos rapports de bugs et demandes de fonctionnalités au suivi des problèmes (dans le sous-système Java. Decompiler. Engine).
Fernflower est fourni avec IntelliJ IDEA et est principalement utilisé pour afficher le code Java lors du débogage ou de la navigation dans les fichiers de classe.
Fernflower peut être exécuté en ligne de commande en mode autonome à l'aide de la commande suivante :
java -jar fernflower.jar [-<option>=<value>]* [<source>]+ <destination>
* signifie zéro ou plusieurs fois
+ signifie une ou plusieurs fois
<source> : fichier ou répertoire contenant les fichiers à décompiler.
Les répertoires sont scannés récursivement.
Les extensions de fichier autorisées sont class, zip et jar.
Les sources préfixées par -e= désignent des fichiers « bibliothèque » qui ne seront pas décompilés mais pris en compte lors de l'analyse des relations entre classes ou méthodes.
En particulier, le renommage des identifiants (voir l'option ren) peut bénéficier des informations sur les classes externes.
<destination> : répertoire de destination pour placer le code source Java résultant
<option>=<value> : une option de ligne de commande avec la valeur correspondante (voir « Options de la ligne de commande » ci-dessous).
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\
Sauf pour mpm et urc, la valeur 1 signifie que l'option est activée, 0 - désactivée.
La valeur par défaut, si elle existe, est donnée entre parenthèses.
Généralement, les options suivantes seront modifiées par l'utilisateur, le cas échéant : hes, hdc, dgs, mpm, ren, urc Les autres options peuvent être laissées telles quelles : elles sont destinées aux ingénieurs en rétro-ingénierie professionnels.
rbr (1) : masquer les méthodes pont (bridge methods)rsy (0) : masquer les membres de classe synthétiquesdin (1) : décompiler les classes internesdc4 (1) : réduire les références de classe 1.4das (1) : décompiler les assertionshes (1) : masquer l'invocation super videhdc (1) : masquer le constructeur par défaut videdgs (0) : décompiler les signatures génériquesner (1) : supposer que le retour ne lève pas d'exceptionsden (1) : décompiler les énumérationsrgn (1) : supprimer l'invocation de getClass() lorsqu'elle fait partie d'une instruction new qualifiéelit (0) : afficher les littéraux numériques « tels quels »Certains obfuscateurs donnent aux classes et à leurs éléments membres des noms courts, insignifiants et surtout ambigus. La recompilation de ce code entraîne un grand nombre de conflits. Par conséquent, il est conseillé de laisser le décompilateur renommer les éléments à son tour, assurant ainsi l'unicité de chaque identifiant.
L'option ren (c'est-à-dire -ren=1) active la fonctionnalité de renommage. La stratégie de renommage par défaut est la suivante :
org.jetbrains.java.decompiler.main.extern.IMemberIdentifierRenamer dans l'option urc
(par exemple -urc=com.example.MyRenamer) à Fernflower. La classe doit être disponible sur le classpath de l'application.La signification de chaque méthode devrait être claire d'après son nom : toBeRenamed détermine si l'élément sera renommé, tandis que les trois autres fournissent respectivement de nouveaux noms pour les classes, les méthodes et les champs.
Construire un script de démarrage exécutable :
./gradlew :installDist
Le script de démarrage est généré dans build/install/engine/bin.
Fernflower fait partie du projet IntelliJ Community, les contributions sont les bienvenues, la manière privilégiée d'envoyer des correctifs est de créer une pull request dans le dépôt de la communauté IntelliJ. Lors de la soumission de correctifs, veuillez suivre les directives de contribution.
Fernflower est sous licence Apache License Version 2.0.
Fernflower a été développé à l'origine par Stiver mais est maintenu par JetBrains depuis 2014. Certains correctifs de ForgeFlower ont été fusionnés dans ce dépôt. Le miroir de Fernflower a également été maintenu par Andrew McRae pendant très longtemps.
Le nom correct est Fernflower, pas FernFlower.
asc (0) : encoder les caractères non ASCII dans les littéraux de chaîne et de caractère sous forme d'échappements Unicodebto (1) : interpréter l'entier 1 comme booléen vrai (solution de contournement pour un bug du compilateur)nns (0) : permettre l'absence d'attribut synthétique (solution de contournement pour un bug du compilateur)uto (1) : considérer les types sans nom comme java.lang.Object (solution de contournement pour un défaut d'architecture du compilateur)udv (1) : reconstruire les noms de variables à partir des informations de débogage, si présentesump (1) : reconstruire les noms de paramètres à partir des attributs correspondants, si présentsrer (1) : supprimer les plages d'exceptions videsfdi (1) : dé-inlinifier les structures finallympm (0) : temps de traitement maximum autorisé par méthode décompilée, en secondes. 0 signifie aucune limiteren (0) : renommer les classes et éléments de classe ambigus (resp. obscurs)urc (-) : nom complet d'une classe fournie par l'utilisateur implémentant l'interface IIdentifierRenamer. Elle est utilisée pour déterminer quels identifiants de classe doivent être renommés et fournit de nouveaux noms d'identifiants (voir « Renommage des identifiants »)inn (1) : vérifier la présence d'annotation @NotNull spécifique à IntelliJ IDEA et supprimer le code inséré si trouvélac (0) : décompiler les expressions lambda en classes anonymesnls (0) : définir un caractère de nouvelle ligne à utiliser pour la sortie. 0 - '\r\n' (Windows), 1 - '\n' (Unix), par défaut dépend du système d'exploitationind : chaîne d'indentation (par défaut 3 espaces)crp (0) : utiliser les motifs d'enregistrement (record patterns) lorsque c'est possiblecps (0) : utiliser switch avec motifs lorsque c'est possiblelog (INFO) : niveau de journalisation, les valeurs possibles sont TRACE, INFO, WARN, ERRORiec (0) : inclure l'intégralité du classpath dans le contexte lors de la décompilationisl (1) : simplifier les expressions lambda simples en ligneucrc (1) : masquer le constructeur et les accesseurs d'enregistrement inutilescci (1) : vérifier si la ressource dans try-with-resources implémente réellement l'interface AutoCloseablejvn (0) : écraser tout nom de variable locale avec des noms de style JADjpr (0) : inclure les noms de paramètres dans le nommage JADpbo (0) : ajouter des parenthèses clarifiantes lorsque les opérateurs binaires/décalage sont mélangés avec des opérateurs arithmétiques