À propos de FernFlower
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. Naturellement, il est encore en développement, veuillez envoyer vos rapports de bogues et suggestions d'amélioration au [issue tracker](https://youtrack.jetbrains.com/newIssue?project=IDEA&clearDraft=true&c=Subsystem+Java. Decompiler).
Fleur de Fougère et Fleur de Forge
FernFlower inclut certains correctifs de ForgeFlower. Nous remercions sincèrement les responsables de ForgeFlower pour leurs précieuses contributions et améliorations.
Licence
FernFlower est sous licence Apache License Version 2.0.
Exécuter à partir de la ligne de commande
java -jar fernflower.jar [-<option>=<value>]* [<source>]+ <destination>
* signifie 0 fois ou plus
+ signifie 1 ou plusieurs fois
<source> : fichier ou répertoire contenant les fichiers à décompiler. Les répertoires sont analysés de manière récursive. Les extensions de fichiers 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 (s. option 'ren') peut bénéficier d'informations sur les classes externes.
<destination> : répertoire de destination
<option>, <value> : une option de ligne de commande avec la valeur correspondante (voir "Options de ligne de commande" ci-dessous).
Exemples :
java -jar fernflower.jar -hes=0 -hdc=0 c:Tempbinary -e=c:Javart.jar c:Tempsource
java -jar fernflower.jar -dgs=1 c:Tempbinarylibrary.jar c:TempbinaryBoot.class c:Tempsource
Options de ligne de commande
À l'exception de mpm et urc, la valeur 1 signifie que l'option est activée, 0 - désactivée. La valeur par défaut, le cas échéant, est indiqué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. Le reste des options peut être laissé tel quel : elles sont destinées aux rétro-ingénieurs professionnels.
- rbr (1): masquer les méthodes de pont
- rsy (0) : masquer les membres de la classe synthétique
- din (1) : décompiler les classes internes
- dc4 (1) : réduire les références de classe 1.4
- ça (1) : décompiler les assertions
- hes (1) : masquer la super invocation vide
- hdc (1): masquer le constructeur par défaut vide
- dgs (0) : décompiler les signatures génériques
- ner (1): suppose que le retour ne lance pas d'exceptions
- den (1) : décompiler les énumérations
- rgn (1) : supprime l'invocation getClass(), lorsqu'elle fait partie d'une nouvelle instruction qualifiée
- allumé (0) : affiche les littéraux numériques "tels quels"
- asc (0) : encode les caractères non-ASCII dans les chaînes et les caractères littéraux lors des échappements Unicode
- bto (1) : interpréter int 1 comme booléen true (solution de contournement à un bug du compilateur)
- nns (0) : autoriser l'attribut synthétique non défini (solution de contournement à un bug du compilateur)
- uto (1) : considérer les types sans nom comme java.lang.Object (solution de contournement à un défaut d'architecture du compilateur)
- udv (1) : reconstruit les noms de variables à partir des informations de débogage, si présentes
- ump (1) : reconstruit les noms de paramètres à partir des attributs correspondants, le cas échéant
- rer (1) : supprimer les plages d'exceptions vides
- fdi (1) : dés-inline finalement les structures
- mpm (0) : temps de traitement maximum autorisé par méthode décompilée, en secondes. 0 signifie pas de limite supérieure
- ren (0) : renommer les classes et les éléments de classe ambigus (resp. obscurcis)
- urc (-) : nom complet d'une classe fournie par l'utilisateur implémentant l'interface IIdentifierRenamer. Il est utilisé pour déterminer quels identifiants de classe doivent être renommés et fournit de nouveaux noms d'identifiant (voir "Renommer les identifiants")
- inn (1) : recherchez l'annotation @NotNull spécifique à IntelliJ IDEA et supprimez le code inséré s'il est trouvé
- lac (0) : décompiler les expressions lambda en classes anonymes
- nls (0) : définit le nouveau caractère de ligne à utiliser pour la sortie. 0 - 'rn' (Windows), 1 - 'n' (Unix), la valeur par défaut dépend du système d'exploitation
- ind : chaîne d'indentation (la valeur par défaut est de 3 espaces)
- crp (0) : utiliser des modèles d'enregistrement là où c'est possible
- cps (0) : utilisez switch avec des motifs là où c'est possible
- log (INFO) : un niveau de journalisation, les valeurs possibles sont TRACE, INFO, WARN, ERROR
- iec (0) : inclure l'intégralité du chemin de classe dans le contexte lors de la décompilation
- isl (1) : expressions lambda simples en ligne
- ucrc (1) : masquer le constructeur d'enregistrements et les getters inutiles
- cci (1) : vérifier si la ressource dans try-with-resources implémente réellement l'interface
AutoCloseable
- jvn (0) : écrasez tous les noms de variables locales par des noms de style JAD
- jpr (0) : inclure les noms de paramètres dans la dénomination JAD
Renommer les identifiants
Certains obfuscateurs donnent aux classes et à leurs éléments membres des noms courts, dénués de sens et surtout ambigus. La recompilation d'un tel code entraîne un grand nombre de conflits. Il est donc conseillé de laisser le décompilateur renommer les éléments à son tour, garantissant ainsi l'unicité de chaque identifiant.
L'option 'ren' (c'est-à-dire -ren=1) active la fonctionnalité de changement de nom. La stratégie de renommage par défaut est la suivante :
- renommer un élément si son nom est un mot réservé ou est inférieur à 3 caractères
- les nouveaux noms sont construits selon un modèle simple : (class|method|field)_<consecutive unique number>
Vous pouvez écraser ces règles en fournissant votre propre implémentation des 4 méthodes clés invoquées par le décompilateur lors du changement de nom. Transmettez simplement une classe qui implémente org.jetbrains.java.decompiler.main.extern.IIdentifierRenamer dans l'option 'urc' (par exemple -urc=com.example.MyRenamer) à FernFlower. La classe doit être disponible sur le chemin de classe de l'application.
La signification de chaque méthode doit être claire lors de la dénomination : 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.