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 at fernflower.decompiler@gmail.com
Fernflower is licensed under the Apache License Version 2.0. It can be found here: http://www.apache.org/licenses/LICENSE-2.0
java -jar fernflower.jar [-<option>=<value>]* [<source>]+ <destination>
*
means 0 or more times
+
means 1 or more times
<source>
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 Renaming identifiers) can benefit from information about external classes.
<destination>
destination directory.
<option>,<value>
command line option with the corresponding value, see Command line options.
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\
With the exception of mpm
and urc
the value of 1 means the option is activated, 0 - deactivated. 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.
rbr (1)
hide bridge methodsrsy (0)
hide synthetic class membersdin (1)
decompile inner classesdc4 (1)
collapse 1.4 class referencesdas (1)
decompile assertionshes (1)
hide empty super invocationhdc (1)
hide empty default constructordgs (0)
decompile generic signaturesner (1)
assume return not throwing exceptionsden (1)
decompile enumerationsrgn (1)
removegetClass()
invocation, when it is part of a qualified new statementlit (0)
output numeric literals "as-is"asc (0)
encode non-ASCII characters in string and character literals as Unicode escapesbto (1)
interpret int 1 as boolean true (workaround to a compiler bug)nns (1)
allow for not set synthetic attribute (workaround to a compiler bug)uto (1)
consider nameless types asjava.lang.Object
(workaround to a compiler architecture flaw)udv (1)
reconstruct variable names from debug information, if presentrer (1)
remove empty exception rangesfdi (1)
de-inline finally structuresmpm (0)
maximum allowed processing time per decompiled method, in seconds. 0 means no upper limitren (0)
rename ambiguous (resp. obfuscated) classes and class elementsurc ()
full name of user-supplied class implementingIIdentifierRenamer
. It is used to determine which class identifiers should be renamed and provides new identifier names. For more information see Renaming identifiersinn (1)
check for IntelliJ IDEA-specific@NotNull
annotation and remove inserted code if foundlac (0)
decompile lambda expressions to anonymous classesnls (0)
define new line character to be used for output. 0 -\r\n
(Windows), 1 -\n
(Unix), default is OS-dependentind (" ")
indentation string (default is 3 spaces)log (INFO)
logging level. Possible values:TRACE
,INFO
,WARN
,ERROR
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 ren
(i.e. -ren=1
) activates renaming functionality.
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 this rules by providing your own implementation of the 4 key methods invoked by the decompiler while renaming. Simply pass a class that implementsorg.jetbrains.java.decompiler.main.extern.IIdentifierRenamer
in the optionurc
(e.g.-urc=com.mypackage.MyRenamer
) to Fernflower. The class must be available on the application classpath.
The meaning of each method should be clear from naming: toBeRenamed
determines whether the element will be renamed, while the other three
provide new names for classes, methods and fields respectively.