Über FernFlower
FernFlower ist der erste tatsächlich funktionierende analytische Dekompiler für Java und wahrscheinlich für eine höhere Programmiersprache im Allgemeinen. Natürlich befindet es sich noch in der Entwicklung. Bitte senden Sie Ihre Fehlerberichte und Verbesserungsvorschläge an den [Issue Tracker](https://youtrack.jetbrains.com/newIssue?project=IDEA&clearDraft=true&c=Subsystem+Java. Decompiler).
FernFlower und ForgeFlower
FernFlower enthält einige Patches von ForgeFlower. Den Betreuern von ForgeFlower gilt ein herzlicher Dank für ihre wertvollen Beiträge und Verbesserungen.
Lizenz
FernFlower ist unter der Apache-Lizenz Version 2.0 lizenziert.
Wird über die Befehlszeile ausgeführt
java -jar fernflower.jar [-<option>=<value>]* [<source>]+ <destination>
* bedeutet 0 oder mehr Mal
+ bedeutet 1 oder mehrere Male
<Quelle>: Datei oder Verzeichnis mit zu dekompilierenden Dateien. Verzeichnisse werden rekursiv durchsucht. Zulässige Dateierweiterungen sind class, zip und jar. Quellen mit dem Präfix -e= bedeuten „Bibliotheksdateien“, die nicht dekompiliert werden, aber bei der Analyse der Beziehungen zwischen Klassen oder Methoden berücksichtigt werden. Insbesondere das Umbenennen von Bezeichnern (s. Option 'ren') kann von Informationen über externe Klassen profitieren.
<Ziel>: Zielverzeichnis
<Option>, <Wert>: eine Befehlszeilenoption mit dem entsprechenden Wert (siehe „Befehlszeilenoptionen“ unten).
Beispiele:
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
Befehlszeilenoptionen
Mit Ausnahme von mpm und urc bedeutet der Wert 1, dass die Option aktiviert ist, 0 - deaktiviert. Der Standardwert, falls vorhanden, wird in Klammern angegeben.
Normalerweise werden die folgenden Optionen vom Benutzer geändert, sofern vorhanden: hes, hdc, dgs, mpm, ren, urc. Die restlichen Optionen können unverändert bleiben: Sie richten sich an professionelle Reverse Engineers.
- rbr (1): Bridge-Methoden ausblenden
- rsy (0): synthetische Klassenmitglieder ausblenden
- din (1): Innere Klassen dekompilieren
- dc4 (1): 1.4-Klassenreferenzen einklappen
- das (1): Behauptungen dekompilieren
- hes (1): leeren Superaufruf ausblenden
- hdc (1): leeren Standardkonstruktor ausblenden
- dgs (0): generische Signaturen dekompilieren
- ner (1): Gehen Sie davon aus, dass die Rückgabe keine Ausnahmen auslöst
- den (1): Aufzählungen dekompilieren
- rgn (1): getClass()-Aufruf entfernen, wenn er Teil einer qualifizierten neuen Anweisung ist
- lit (0): numerische Literale „wie sie sind“ ausgeben
- asc (0): Codieren Sie Nicht-ASCII-Zeichen in Zeichenfolgen- und Zeichenliteralen als Unicode-Escapezeichen
- bto (1): Interpretiere int 1 als boolean true (Problemumgehung für einen Compiler-Fehler)
- nns (0): Nicht festgelegtes synthetisches Attribut zulassen (Umgehung eines Compiler-Fehlers)
- uto (1): Betrachten Sie namenlose Typen als java.lang.Object (Umgehung eines Compiler-Architekturfehlers)
- udv (1): Variablennamen aus Debug-Informationen rekonstruieren, falls vorhanden
- ump (1): Parameternamen aus entsprechenden Attributen rekonstruieren, falls vorhanden
- rer (1): Leere Ausnahmebereiche entfernen
- fdi (1): Deinline-Finally-Strukturen
- mpm (0): maximal zulässige Verarbeitungszeit pro dekompilierter Methode in Sekunden. 0 bedeutet keine Obergrenze
- ren (0): mehrdeutige (bzw. verschleierte) Klassen und Klassenelemente umbenennen
- urc (-): vollständiger Name einer vom Benutzer bereitgestellten Klasse, die die IIdentifierRenamer-Schnittstelle implementiert. Es wird verwendet, um zu bestimmen, welche Klassenbezeichner umbenannt werden sollen, und stellt neue Bezeichnernamen bereit (siehe „Bezeichner umbenennen“).
- inn (1): Suchen Sie nach der IntelliJ IDEA-spezifischen @NotNull-Annotation und entfernen Sie den eingefügten Code, wenn er gefunden wird
- lac (0): Lambda-Ausdrücke in anonyme Klassen dekompilieren
- nls (0): Definieren Sie das neue Zeilenzeichen, das für die Ausgabe verwendet werden soll. 0 – „rn“ (Windows), 1 – „n“ (Unix), Standard ist betriebssystemabhängig
- ind: Einrückungszeichenfolge (Standard sind 3 Leerzeichen)
- crp (0): Verwenden Sie Aufzeichnungsmuster, wo es möglich ist
- cps (0): Verwenden Sie den Schalter mit Mustern, wo es möglich ist
- log (INFO): eine Protokollierungsstufe, mögliche Werte sind TRACE, INFO, WARN, ERROR
- iec (0): Bezieht beim Dekompilieren den gesamten Klassenpfad in den Kontext ein
- isl (1): einfache Inline-Lambda-Ausdrücke
- ucrc (1): Unnötigen Datensatzkonstruktor und Getter ausblenden
- cci (1): Überprüfen Sie, ob die Ressource in try-with-resources tatsächlich
AutoCloseable
-Schnittstelle implementiert - jvn (0): Überschreiben Sie alle lokalen Variablennamen mit Namen im JAD-Stil
- jpr (0): Parameternamen in die JAD-Benennung einbeziehen
Bezeichner umbenennen
Einige Obfuskatoren geben Klassen und ihren Mitgliedselementen kurze, bedeutungslose und vor allem mehrdeutige Namen. Das Neukompilieren eines solchen Codes führt zu einer Vielzahl von Konflikten. Daher ist es ratsam, den Dekompiler seinerseits die Elemente umbenennen zu lassen, um die Eindeutigkeit jedes Bezeichners sicherzustellen.
Die Option „ren“ (dh -ren=1) aktiviert die Umbenennungsfunktion. Die standardmäßige Umbenennungsstrategie lautet wie folgt:
- Benennen Sie ein Element um, wenn sein Name ein reserviertes Wort ist oder kürzer als 3 Zeichen ist
- Neue Namen werden nach einem einfachen Muster erstellt: (Klasse|Methode|Feld)_<aufeinanderfolgende eindeutige Nummer>
Sie können diese Regeln überschreiben, indem Sie Ihre eigene Implementierung der vier Schlüsselmethoden bereitstellen, die vom Dekompiler beim Umbenennen aufgerufen werden. Übergeben Sie einfach eine Klasse, die org.jetbrains.java.decompiler.main.extern.IIdentifierRenamer implementiert, in der Option „urc“ (z. B. -urc=com.example.MyRenamer) an FernFlower. Die Klasse muss im Klassenpfad der Anwendung verfügbar sein.
Die Bedeutung jeder Methode sollte aus der Benennung klar hervorgehen: toBeRenamed bestimmt, ob das Element umbenannt wird, während die anderen drei jeweils neue Namen für Klassen, Methoden und Felder bereitstellen.