Convert Figma logo to code with AI

fesh0r logofernflower

Unofficial mirror of FernFlower Java decompiler (All pulls should be submitted upstream)

3,436
648
3,436
1

Top Related Projects

IntelliJ IDEA Community Edition & IntelliJ Platform

2,014

This is the public repository for the CFR Java decompiler

41,326

Dex to Java decompiler

A Java 8+ Jar & Android APK Reverse Engineering Suite (Decompiler, Editor, Debugger & More)

4,999

An Open Source Java Decompiler Gui for Procyon

14,011

A standalone Java Decompiler GUI

Quick Overview

Fernflower is an analytical decompiler for Java, developed by JetBrains and maintained by fesh0r on GitHub. It aims to produce high-quality Java source code from compiled class files, making it useful for reverse engineering and code analysis tasks.

Pros

  • Produces readable and well-structured Java source code
  • Supports decompilation of modern Java features and language constructs
  • Actively maintained and regularly updated
  • Can be used as a standalone tool or integrated into other projects

Cons

  • May struggle with heavily obfuscated code
  • Slower performance compared to some other decompilers
  • Limited documentation and examples available
  • Occasional issues with complex lambda expressions or nested classes

Code Examples

As Fernflower is a decompiler and not a code library, there are no code examples to provide. Instead, it is used as a tool to decompile Java bytecode into source code.

Getting Started

To use Fernflower, follow these steps:

  1. Clone the repository:

    git clone https://github.com/fesh0r/fernflower.git
    
  2. Build the project using Gradle:

    cd fernflower
    ./gradlew build
    
  3. Use the built JAR file to decompile a class file:

    java -jar build/libs/fernflower.jar <input_file.class> <output_directory>
    

Replace <input_file.class> with the path to your compiled Java class file and <output_directory> with the desired output location for the decompiled source code.

Competitor Comparisons

IntelliJ IDEA Community Edition & IntelliJ Platform

Pros of intellij-community

  • Comprehensive IDE functionality with a wide range of features and plugins
  • Active development with frequent updates and improvements
  • Large community support and extensive documentation

Cons of intellij-community

  • Larger codebase and more complex architecture
  • Higher resource requirements for development and usage
  • Steeper learning curve for contributors

Code Comparison

fernflower (Java decompiler):

public class ByteCodeAnalyzer {
    public static String decompile(byte[] bytecode) {
        // Decompilation logic here
    }
}

intellij-community (IDE functionality):

public class JavaDecompiler {
    public String decompile(VirtualFile file, Project project) {
        // Decompilation logic integrated with IDE
    }
}

Summary

fernflower is a focused Java decompiler project, while intellij-community is a comprehensive IDE platform. fernflower offers a simpler, more specialized codebase for Java decompilation, while intellij-community provides a full-featured development environment with integrated decompilation capabilities. The choice between them depends on whether you need a standalone decompiler or a complete IDE solution.

2,014

This is the public repository for the CFR Java decompiler

Pros of CFR

  • More actively maintained with frequent updates
  • Supports decompilation of newer Java versions (up to Java 17)
  • Offers additional features like enum and switch expression decompilation

Cons of CFR

  • May produce more verbose output in some cases
  • Less widespread adoption compared to Fernflower
  • Potentially slower decompilation speed for large projects

Code Comparison

CFR:

public class Example {
    public static void main(String[] args) {
        System.out.println("Hello, CFR!");
    }
}

Fernflower:

public class Example {
    public static void main(String[] args) {
        System.out.println("Hello, Fernflower!");
    }
}

Both decompilers produce similar output for simple Java code. However, CFR may generate more detailed comments and handle complex language features better in some cases.

Summary

CFR and Fernflower are both Java decompilers with their own strengths. CFR excels in supporting newer Java versions and offering additional decompilation features, while Fernflower has been widely adopted and integrated into various tools. The choice between them depends on specific project requirements and personal preferences.

41,326

Dex to Java decompiler

Pros of jadx

  • More actively maintained with frequent updates
  • Includes a GUI for easier navigation and analysis
  • Supports decompilation of Android resources (XML, manifest)

Cons of jadx

  • May struggle with heavily obfuscated code
  • Can be slower for large projects compared to fernflower

Code comparison

fernflower:

public class HelloWorld {
    public static void main(String[] args) {
        System.out.println("Hello, World!");
    }
}

jadx:

public class HelloWorld {
    public static void main(String[] args) {
        System.out.println("Hello, World!");
    }
}

In this simple example, both decompilers produce identical output. However, differences may become apparent with more complex code structures or when dealing with obfuscated binaries.

jadx generally produces more readable code for Android-specific constructs and can handle newer Java language features better. fernflower, being integrated into IntelliJ IDEA, benefits from the IDE's code analysis capabilities but may lag behind in supporting the latest Java syntax.

Both tools have their strengths, with jadx being more suited for Android-focused reverse engineering tasks, while fernflower excels in general Java decompilation within the IntelliJ ecosystem.

A Java 8+ Jar & Android APK Reverse Engineering Suite (Decompiler, Editor, Debugger & More)

Pros of Bytecode Viewer

  • Offers a comprehensive GUI with multiple decompiler options
  • Includes additional features like searching, editing, and compiling
  • Supports various file formats beyond just Java class files

Cons of Bytecode Viewer

  • Larger file size and more complex setup compared to FernFlower
  • May have slower performance due to its extensive feature set
  • Requires more system resources to run effectively

Code Comparison

FernFlower (command-line usage):

java -jar fernflower.jar input.jar output

Bytecode Viewer (Java code to open a file):

BytecodeViewer.openFiles(new File[]{new File("input.jar")});
BytecodeViewer.viewer.setVisible(true);

Summary

FernFlower is a lightweight, command-line Java decompiler focused solely on decompilation. It's efficient and easy to use for simple decompilation tasks. Bytecode Viewer, on the other hand, is a feature-rich GUI application that incorporates multiple decompilers (including FernFlower) and provides additional tools for bytecode analysis and manipulation. While Bytecode Viewer offers more functionality, it comes at the cost of increased complexity and resource usage. The choice between the two depends on the user's specific needs and preferences.

4,999

An Open Source Java Decompiler Gui for Procyon

Pros of Luyten

  • User-friendly GUI for easier decompilation and navigation
  • Supports multiple output formats (e.g., Java, Groovy)
  • Actively maintained with regular updates

Cons of Luyten

  • May be slower for large-scale decompilation tasks
  • Less suitable for integration into automated workflows
  • Limited command-line interface options

Code Comparison

Fernflower (Java decompilation):

public class Example {
    public static void main(String[] args) {
        System.out.println("Hello, World!");
    }
}

Luyten (Java decompilation):

public class Example {
    public static void main(final String[] args) {
        System.out.println("Hello, World!");
    }
}

Both tools produce similar output for simple Java code. However, Fernflower may handle more complex scenarios with slightly better accuracy, while Luyten offers a more user-friendly interface for exploring decompiled code.

Summary

Fernflower is better suited for large-scale decompilation tasks and integration into automated workflows, while Luyten provides a more accessible GUI-based approach for individual developers. The choice between the two depends on specific use cases and user preferences.

14,011

A standalone Java Decompiler GUI

Pros of JD-GUI

  • User-friendly graphical interface for easy navigation and decompilation
  • Real-time decompilation and syntax highlighting
  • Supports drag-and-drop functionality for quick file loading

Cons of JD-GUI

  • Less actively maintained compared to Fernflower
  • Limited command-line options and automation capabilities
  • May produce less accurate decompiled code in some cases

Code Comparison

Fernflower:

public class Example {
    public static void main(String[] args) {
        System.out.println("Hello, World!");
    }
}

JD-GUI:

public class Example
{
  public static void main(String[] paramArrayOfString)
  {
    System.out.println("Hello, World!");
  }
}

Both decompilers produce similar output for simple code, but Fernflower often generates more readable and accurate results for complex classes and methods. JD-GUI may introduce unnecessary line breaks and use different parameter naming conventions.

Fernflower is generally preferred for its accuracy and integration with other tools, while JD-GUI offers a more user-friendly interface for quick visual inspection of decompiled code. The choice between the two depends on the specific use case and user preferences.

Convert Figma logo designs to code with AI

Visual Copilot

Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.

Try Visual Copilot

README

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.

Fernflower and ForgeFlower

Fernflower includes some patches from ForgeFlower. Sincere appreciation is extended to the maintainers of ForgeFlower for their valuable contributions and enhancements.

Licence

Fernflower is licenced under the Apache Licence Version 2.0.

Running from command line

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 analysing relationships between classes or methods. Especially renaming of identifiers (s. option 'ren') can benefit from information about external classes.

<destination>: destination directory

<option>, <value>: a command-line option with the corresponding value (see "Command-line options" below).

Examples:

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\

Command-line options

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 methods
  • rsy (0): hide synthetic class members
  • din (1): decompile inner classes
  • dc4 (1): collapse 1.4 class references
  • das (1): decompile assertions
  • hes (1): hide empty super invocation
  • hdc (1): hide empty default constructor
  • dgs (0): decompile generic signatures
  • ner (1): assume return not throwing exceptions
  • den (1): decompile enumerations
  • rgn (1): remove getClass() invocation, when it is part of a qualified new statement
  • lit (0): output numeric literals "as-is"
  • asc (0): encode non-ASCII characters in string and character literals as Unicode escapes
  • bto (1): interpret int 1 as boolean true (workaround to a compiler bug)
  • nns (0): allow for not set synthetic attribute (workaround to a compiler bug)
  • uto (1): consider nameless types as java.lang.Object (workaround to a compiler architecture flaw)
  • udv (1): reconstruct variable names from debug information, if present
  • ump (1): reconstruct parameter names from corresponding attributes, if present
  • rer (1): remove empty exception ranges
  • fdi (1): de-inline finally structures
  • mpm (0): maximum allowed processing time per decompiled method, in seconds. 0 means no upper limit
  • ren (0): rename ambiguous (resp. obfuscated) classes and class elements
  • urc (-): full name of a user-supplied class implementing IIdentifierRenamer interface. It is used to determine which class identifiers should be renamed and provides new identifier names (see "Renaming identifiers")
  • inn (1): check for IntelliJ IDEA-specific @NotNull annotation and remove inserted code if found
  • lac (0): decompile lambda expressions to anonymous classes
  • nls (0): define new line character to be used for output. 0 - '\r\n' (Windows), 1 - '\n' (Unix), default is OS-dependent
  • ind: indentation string (default is 3 spaces)
  • crp (0): use record patterns where it is possible
  • cps (0): use switch with patterns where it is possible
  • log (INFO): a logging level, possible values are TRACE, INFO, WARN, ERROR
  • iec (0): include entire class path into context when decompiling
  • isl (1): inline simple lambda expressions
  • ucrc (1): hide unnecessary record constructor and getters
  • cci (1): check if resource in try-with-resources actually implements AutoCloseable interface
  • jvn (0): overwrite any local variable names with JAD style names
  • jpr (0): include parameter names in JAD naming

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 '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 implements org.jetbrains.java.decompiler.main.extern.IIdentifierRenamer in the option 'urc' (e.g. -urc=com.example.MyRenamer) to Fernflower. The class must be available on the application classpath.

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.