fernflower
Описание
Decompiler from Java bytecode to Java, used in IntelliJ IDEA.
Языки
- Java99,9%
- Остальные0,1%
Fernflower
A decompiler from Java bytecode to Java.
About Fernflower
Fernflower is the first actually working analytical decompiler for Java
and probably for a high-level programming language in general.
Naturally, it is still under development.
Please send your bug reports and improvement suggestions to the issue tracker (in subsystem ).
Naming
The correct name is Fernflower, not FernFlower.
Credits
Fernflower was originally written by Stiver.
Fernflower includes some patches from ForgeFlower. Sincere appreciation is extended to the maintainers of ForgeFlower for their valuable contributions and enhancements.
A mirror of this repository has been maintained for many years by Andrew McRae until JetBrains offered to take over. Sincere appreciation is extended to Andrew for his work maintaining the mirror.
License
Fernflower is licensed under the Apache License Version 2.0.
Usage
IntelliJ
The Fernflower IDE plugin is bundled in IntelliJ IDEA.
Open any file and you should see the decompiled Java source code: this is Fernflower in action.
The plugin is also open-source and can be found here.
Running from the command line
means zero or more times
means one or more times
: file or directory with files to be decompiled.
Directories are recursively scanned.
Allowed file extensions are class, zip and jar.
Sources prefixed with -e= mean "library" files that won't be decompiled but taken into account when analyzing
relationships between classes or methods.
Especially renaming of identifiers (see the option) can benefit from information about external classes.
: destination directory to place the resulting Java source into
: a command-line option with the corresponding value (see "Command-line options" below).
Examples
Command-line options
Except for and the value of 1 means the option is activated, 0 - deactivated.
The default value, if any, is given between parentheses.
Typically, the following options will be changed by user, if any: hes, hdc, dgs, mpm, ren, urc The rest of options can be left as they are: they are aimed at professional reverse engineers.
(1): hide bridge methodsrbr(0): hide synthetic class membersrsy(1): decompile inner classesdin(1): collapse 1.4 class referencesdc4(1): decompile assertionsdas(1): hide empty super invocationhes(1): hide empty default constructorhdc(0): decompile generic signaturesdgs(1): assume return not throwing exceptionsner(1): decompile enumerationsden(1): removergninvocation, when it is part of a qualified new statementgetClass()(0): output numeric literals "as-is"lit(0): encode non-ASCII characters in string and character literals as Unicode escapesasc(1): interpret int 1 as boolean true (workaround to a compiler bug)bto(0): allow for not set synthetic attribute (workaround to a compiler bug)nns(1): consider nameless types asuto(workaround to a compiler architecture flaw)java.lang.Object(1): reconstruct variable names from debug information, if presentudv(1): reconstruct parameter names from corresponding attributes, if presentump(1): remove empty exception rangesrer(1): de-inline finally structuresfdi(0): maximum allowed processing time per decompiled method, in seconds. 0 means no upper limitmpm(0): rename ambiguous (resp. obfuscated) classes and class elementsren(-): full name of a user-supplied class implementingurcinterface. It is used to determine which class identifiers should be renamed and provides new identifier names (see "Renaming identifiers")IIdentifierRenamer(1): check for IntelliJ IDEA-specific @NotNull annotation and remove inserted code if foundinn(0): decompile lambda expressions to anonymous classeslac(0): define a new line character to be used for output. 0 -nls(Windows), 1 -'\r\n'(Unix), default is OS-dependent'\n': indentation string (default is 3 spaces)ind(0): use record patterns where it is possiblecrp(0): use switch with patterns where it is possiblecps(INFO): a logging level, possible values are TRACE, INFO, WARN, ERRORlog(0): include the entire classpath in context when decompilingiec(1): inline simple lambda expressionsisl(1): hide unnecessary record constructor and gettersucrc(1): check if resource in try-with-resources actually implementscciinterfaceAutoCloseable(0): overwrite any local variable names with JAD style namesjvn(0): include parameter names in JAD namingjpr
Renaming identifiers
Some obfuscators give classes and their member elements short, meaningless and above all ambiguous names. Recompiling of such code leads to a great number of conflicts. Therefore, it is advisable to let the decompiler rename elements in its turn, ensuring uniqueness of each identifier.
Option (i.e. ) activates renaming functionality. The default renaming strategy goes as follows:
- rename an element if its name is a reserved word or is shorter than 3 characters
- new names are built according to a simple pattern: (class|method|field)_<consecutive unique number>
You can overwrite these rules by providing your own implementation of the 4 key methods invoked by the decompiler while renaming. Simply pass a class that implementsin the optionorg.jetbrains.java.decompiler.main.extern.IMemberIdentifierRenamer(e.g. -urc=com.example.MyRenamer) to Fernflower. The class must be available on the application classpath.urc
The meaning of each method should be clear from naming: toBeRenamed determine whether the element will be renamed, while the other three provide new names for classes, methods and fields respectively.
Development
Build an executable start-up script:
The startup script is generated in .