
Decompilador de bytecode de Java a Java, usado en IntelliJ IDEA.
Fernflower es el primer descompilador analítico que realmente funciona para Java y probablemente para un lenguaje de programación de alto nivel en general.
Las versiones se publican en el repositorio de IntelliJ Community.
Envía tus informes de errores y solicitudes de funciones al issue tracker (en el subsistema Java. Decompiler. Engine).
Fernflower se incluye en IntelliJ IDEA y se usa principalmente para mostrar código Java al depurar o navegar por archivos de clase.
Fernflower se puede ejecutar desde la línea de comandos en modo independiente usando el siguiente comando:
java -jar fernflower.jar [-<option>=<value>]* [<source>]+ <destination>
* significa cero o más veces
+ significa una o más veces
<source>: archivo o directorio con archivos a descompilar.
Los directorios se escanean recursivamente.
Las extensiones de archivo permitidas son class, zip y jar.
Las fuentes con el prefijo -e= significan archivos "biblioteca" que no se descompilarán pero se tendrán en cuenta al analizar
relaciones entre clases o métodos.
Especialmente el renombrado de identificadores (ver la opción ) puede beneficiarse de la información sobre clases externas.
ren<destination>: directorio de destino para colocar el código Java resultante.
<option>=<value>: una opción de línea de comandos con el valor correspondiente (ver "Opciones de línea de comandos" más abajo).
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\
Excepto para mpm y urc, el valor 1 significa que la opción está activada, 0 - desactivada.
El valor por defecto, si lo hay, se indica entre paréntesis.
Normalmente, las siguientes opciones serán cambiadas por el usuario, si es que se cambian: hes, hdc, dgs, mpm, ren, urc El resto de opciones se pueden dejar como están: están pensadas para ingenieros inversos profesionales.
rbr (1): ocultar métodos puentersy (0): ocultar miembros de clase sintéticosdin (1): descompilar clases internasdc4 (1): colapsar referencias a clases 1.4das (1): descompilar asercioneshes (1): ocultar invocación vacía a superhdc (1): ocultar constructor por defecto vacíodgs (0): descompilar firmas genéricasner (1): asumir que el retorno no lanza excepcionesden (1): descompilar enumeracionesrgn (1): eliminar invocación a getClass() cuando forma parte de una sentencia new calificadalit (0): mostrar literales numéricos "tal cual"asc (0): codificar caracteres no ASCII en literales de cadena y carácter como escapes Unicodebto (1): interpretar int 1 como booleano true (solución alternativa para un error del compilador)nns (0): permitir que no se establezca el atributo sintético (solución alternativa para un error del compilador)uto (1): considerar tipos sin nombre como java.lang.Object (solución alternativa para una falla de arquitectura del compilador)udv (1): reconstruir nombres de variables a partir de información de depuración, si está presenteump (1): reconstruir nombres de parámetros a partir de atributos correspondientes, si están presentesrer (1): eliminar rangos de excepción vacíosfdi (1): desenlinear estructuras finallympm (0): tiempo máximo de procesamiento permitido por método descompilado, en segundos. 0 significa sin límite superiorren (0): renombrar clases y elementos de clase ambiguos (resp. ofuscados)urc (-): nombre completo de una clase proporcionada por el usuario que implementa la interfaz IIdentifierRenamer. Se utiliza para determinar qué identificadores de clase deben renombrarse y proporciona nuevos nombres de identificador (ver "Renombrado de identificadores")inn (1): buscar la anotación @NotNull específica de IntelliJ IDEA y eliminar el código insertado si se encuentralac (0): descompilar expresiones lambda a clases anónimasnls (0): definir un carácter de nueva línea para la salida. 0 - '\r\n' (Windows), 1 - '\n' (Unix), por defecto depende del SOind: cadena de sangría (por defecto 3 espacios)crp (0): usar patrones de registro donde sea posiblecps (0): usar switch con patrones donde sea posiblelog (INFO): nivel de registro, valores posibles: TRACE, INFO, WARN, ERRORiec (0): incluir todo el classpath en el contexto al descompilarisl (1): enlinealizar expresiones lambda simplesucrc (1): ocultar constructor y getters de registro innecesarioscci (1): comprobar si el recurso en try-with-resources realmente implementa la interfaz AutoCloseablejvn (0): sobrescribir cualquier nombre de variable local con nombres de estilo JADjpr (0): incluir nombres de parámetros en el nombrado JADpbo (0): agregar paréntesis aclaratorios cuando los operadores bitwise/desplazamiento se mezclan con aritméticosAlgunos ofuscadores dan a las clases y a sus elementos miembros nombres cortos, sin significado y, sobre todo, ambiguos. Recompilar dicho código conduce a una gran cantidad de conflictos. Por lo tanto, es recomendable dejar que el descompilador renombre los elementos a su vez, asegurando la unicidad de cada identificador.
La opción ren (es decir, -ren=1) activa la funcionalidad de renombrado. La estrategia de renombrado por defecto es la siguiente:
org.jetbrains.java.decompiler.main.extern.IMemberIdentifierRenamer en la opción urc
(por ejemplo, -urc=com.example.MyRenamer) a Fernflower. La clase debe estar disponible en el classpath de la aplicación.El significado de cada método debería quedar claro por el nombre: toBeRenamed determina si el elemento será renombrado, mientras que los otros tres proporcionan nuevos nombres para clases, métodos y campos respectivamente.
Compilar un script de inicio ejecutable:
./gradlew :installDist
El script de inicio se genera en build/install/engine/bin.
Fernflower es parte del proyecto IntelliJ Community, las contribuciones son bienvenidas; la forma preferida de enviar parches es creando una pull request en el repositorio de IntelliJ Community. Al enviar parches, por favor sigue las directrices de contribución.
Fernflower está licenciado bajo la Apache License Version 2.0.
Fernflower fue desarrollado originalmente por Stiver pero ha sido mantenido por JetBrains desde 2014. Algunos parches de ForgeFlower se fusionaron en este repositorio. El espejo de Fernflower también fue mantenido por Andrew McRae durante mucho tiempo.
El nombre correcto es Fernflower, no FernFlower.