
Java 바이트코드를 Java로 디컴파일하는 도구로, IntelliJ IDEA에서 사용됩니다.
Fernflower는 Java용으로, 아마도 일반적인 고급 프로그래밍 언어용으로는 최초로 실제로 작동하는 분석적 디컴파일러입니다.
릴리스는 Intellij Community 저장소에 게시됩니다.
버그 리포트와 기능 요청은 이슈 트래커 (하위 시스템 Java. Decompiler. Engine)로 보내주세요.
Fernflower는 IntelliJ IDEA에 번들로 포함되어 있으며, 주로 디버깅 시 또는 클래스 파일 탐색 시 Java 코드를 표시하는 데 사용됩니다.
Fernflower는 다음 명령을 사용하여 독립 실행형 모드로 명령줄에서 실행할 수 있습니다:
java -jar fernflower.jar [-<option>=<value>]* [<source>]+ <destination>
*는 0회 이상 반복을 의미합니다.
+는 1회 이상 반복을 의미합니다.
<source>: 디컴파일할 파일 또는 디렉터리입니다.
디렉터리는 재귀적으로 검색됩니다.
허용되는 파일 확장자는 class, zip 및 jar입니다.
-e= 접두사가 붙은 소스는 "라이브러리" 파일을 의미하며, 디컴파일되지는 않지만 클래스나 메서드 간의 관계를 분석할 때 고려됩니다.
특히 식별자 이름 변경(ren 옵션 참조)은 외부 클래스에 대한 정보를 통해 이점을 얻을 수 있습니다.
<destination>: 결과 Java 소스를 배치할 대상 디렉터리입니다.
<option>=<value>: 해당 값이 있는 명령줄 옵션입니다(아래 "명령줄 옵션" 참조).
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\
mpm 및 urc를 제외하고 값 1은 활성화, 0은 비활성화를 의미합니다.
기본값이 있는 경우 괄호 안에 표시됩니다.
일반적으로 사용자가 변경할 가능성이 있는 옵션(있는 경우)은 다음과 같습니다: hes, hdc, dgs, mpm, ren, urc 나머지 옵션은 그대로 둘 수 있으며, 전문 리버스 엔지니어를 대상으로 합니다.
rbr (1): 브릿지 메서드 숨기기rsy (0): 합성 클래스 멤버 숨기기din (1): 내부 클래스 디컴파일dc4 (1): 1.4 클래스 참조 축소das (1): assertion 디컴파일hes (1): 빈 super 호출 숨기기hdc (1): 빈 기본 생성자 숨기기dgs (0): 제네릭 시그니처 디컴파일ner (1): 예외를 던지지 않는 반환 가정den (1): 열거형 디컴파일rgn (1): qualified new 문의 일부인 getClass() 호출 제거lit (0): 숫자 리터럴을 "있는 그대로" 출력asc (0): 문자열 및 문자 리터럴의 비ASCII 문자를 유니코드 이스케이프로 인코딩일부 난독화 도구는 클래스와 그 멤버 요소에 짧고 의미 없으며 무엇보다 모호한 이름을 부여합니다. 이러한 코드를 다시 컴파일하면 많은 충돌이 발생합니다. 따라서 디컴파일러가 요소 이름을 변경하여 각 식별자의 고유성을 보장하는 것이 좋습니다.
ren 옵션(즉, -ren=1)은 이름 변경 기능을 활성화합니다. 기본 이름 변경 전략은 다음과 같습니다:
urc 옵션에 org.jetbrains.java.decompiler.main.extern.IMemberIdentifierRenamer를 구현하는 클래스를 전달하세요
(예: -urc=com.example.MyRenamer) Fernflower에 전달합니다. 클래스는 애플리케이션 클래스패스에서 사용 가능해야 합니다.각 메서드의 의미는 이름에서 명확해야 합니다: toBeRenamed는 요소 이름을 변경할지 여부를 결정하고, 나머지 세 개는 각각 클래스, 메서드, 필드에 대한 새 이름을 제공합니다.
실행 가능한 시작 스크립트 빌드:
./gradlew :installDist
시작 스크립트는 build/install/engine/bin에 생성됩니다.
Fernflower는 IntelliJ Community 프로젝트의 일부이며, 기여를 환영합니다. 패치를 보내는 선호하는 방법은 IntelliJ Community 저장소에 풀 리퀘스트를 생성하는 것입니다. 패치를 제출할 때는 기여 지침을 따라주세요.
Fernflower는 Apache License Version 2.0에 따라 라이선스가 부여됩니다.
Fernflower는 원래 Stiver가 개발했지만 2014년부터 JetBrains에서 유지 관리하고 있습니다. 일부 패치는 ForgeFlower에서 이 저장소로 병합되었습니다. Fernflower의 미러는 Andrew McRae가 오랫동안 유지 관리했습니다.
올바른 이름은 Fernflower이며, FernFlower가 아닙니다.
bto (1): int 1을 boolean true로 해석 (컴파일러 버그에 대한 해결 방법)nns (0): 설정되지 않은 합성 속성 허용 (컴파일러 버그에 대한 해결 방법)uto (1): 이름 없는 타입을 java.lang.Object로 간주 (컴파일러 아키텍처 결함에 대한 해결 방법)udv (1): 디버그 정보가 있으면 변수 이름 재구성ump (1): 해당 속성이 있으면 매개변수 이름 재구성rer (1): 빈 예외 범위 제거fdi (1): finally 구조 인라인 해제mpm (0): 디컴파일된 메서드당 최대 허용 처리 시간(초). 0은 제한 없음ren (0): 모호한(난독화된) 클래스 및 클래스 요소 이름 변경urc (-): IIdentifierRenamer 인터페이스를 구현하는 사용자 제공 클래스의 전체 이름. 어떤 클래스 식별자의 이름을 바꿀지 결정하고 새 식별자 이름을 제공합니다("식별자 이름 변경" 참조)inn (1): IntelliJ IDEA 특정 @NotNull 어노테이션을 확인하고 발견된 삽입 코드 제거lac (0): 람다 표현식을 익명 클래스로 디컴파일nls (0): 출력에 사용할 새 줄 문자 정의. 0 - '\r\n' (Windows), 1 - '\n' (Unix), 기본값은 OS에 따라 다름ind: 들여쓰기 문자열 (기본값은 공백 3개)crp (0): 가능한 경우 레코드 패턴 사용cps (0): 가능한 경우 패턴이 있는 switch 사용log (INFO): 로깅 수준, 가능한 값은 TRACE, INFO, WARN, ERRORiec (0): 디컴파일 시 전체 클래스패스를 컨텍스트에 포함isl (1): 간단한 람다 표현식 인라인ucrc (1): 불필요한 레코드 생성자 및 getter 숨기기cci (1): try-with-resources의 리소스가 실제로 AutoCloseable 인터페이스를 구현하는지 확인jvn (0): 모든 로컬 변수 이름을 JAD 스타일 이름으로 덮어쓰기jpr (0): JAD 이름 지정에 매개변수 이름 포함pbo (0): 비트 연산자/시프트 연산자가 산술 연산자와 혼합될 때 명확성을 위해 괄호 추가