
Krakatau는 Java 바이트코드를 위한 어셈블러와 디스어셈블러를 제공합니다. 이를 통해 바이너리 클래스파일을 사람이 읽을 수 있는 텍스트 형식으로 변환하고, 변경한 후 다시 클래스파일로 변환할 수 있으며, 난독화된 코드에서도 가능합니다. 또한 수동으로 바이트코드를 작성하여 처음부터 자신만의 클래스파일을 생성할 수 있으며, Java 바이너리의 저수준 세부 사항을 검토하고 비교할 수 있습니다. javap와 달리, Krakatau 디스어셈블러는 고도로 난독화된 코드도 처리할 수 있으며, 디스어셈블된 출력을 다시 클래스파일로 재조립할 수 있습니다.
Krakatau는 Java 바이너리를 읽을 수 있는 소스 코드로 변환하는 디컴파일러도 제공합니다. 다른 디컴파일러와 달리, Krakatau 디컴파일러는 난독화된 코드를 대상으로 특별히 설계되어 다른 디컴파일러를 망가뜨리는 트릭을 쉽게 처리할 수 있습니다. 그러나 Krakatau 디컴파일러는 람다와 같은 일부 Java 8+ 기능을 지원하지 않으므로, 오래된 코드에서 가장 잘 작동합니다.
Krakatau의 어셈블러 구문은 대부분 Jasmin 구문의 상위 집합이며 약간의 비호환성이 있지만, Jasmin과 달리 Krakatau는 Java 19 바이트코드 사양을 완전히 지원하며 이전 JVM 버전에서 발견된 일부 문서화되지 않은 기능도 지원합니다. 어셈블러 구문에 대한 개요는 튜토리얼 또는 전체 사양을 참조하십시오.
먼저 Rust와 Cargo를 설치해야 합니다. 그런 다음 이 리포지토리를 클론하고 cargo build --release를 실행합니다. 그러면 target/release/krak2에 바이너리가 생성되며, 이를 직접 호출하거나 PATH에 추가하거나 심볼릭 링크를 걸 수 있습니다.
디스어셈블러에는 기본(default) 모드와 라운드트립(roundtrip) 모드 두 가지가 있습니다. 기본 모드는 결과 어셈블리 파일의 가독성과 수정 용이성에 최적화되어 있습니다. 출력이 재조립되면 JVM 사양 관점에서 원본과 동작이 동등한 클래스파일이 생성되지만, 반드시 비트 단위로 동일하지는 않습니다(예: 상수 풀 항목이 재정렬될 수 있음). 라운드트립 모드는 재조립 시 원본과 비트 단위로 동일한 클래스파일을 생성하는 출력을 제공하지만, 이는 어셈블리 파일이 상수 풀 항목의 정확한 순서와 같은 저수준 인코딩 정보를 유지하여 읽기 어렵게 만듭니다. CLDC 코드나 Scala 코드와 같이 비표준 속성에 의존하는 코드를 다룰 때는 라운드트립 모드를 사용하는 것이 좋습니다.
사용 예:
krak2 dis --out temp RecordTest.class
krak2 dis --out disassembled.zip --roundtrip r0lling-challenge.jar
개별 클래스파일 또는 전체 jar 파일을 디스어셈블할 수 있습니다. 입력 파일명이 .jar 또는 .zip으로 끝나면 jar 파일로 처리되어 jar 내부의 모든 .class 파일이 디스어셈블됩니다.
--out 옵션은 출력 위치를 제어합니다. --out 값이 디렉터리이면 출력이 해당 디렉터리 아래의 개별 파일로 배치됩니다. 그렇지 않고 --out 값이 .jar 또는 .zip으로 끝나면 출력이 해당 위치의 단일 zip 파일로 배치됩니다. --out 값이 .j로 끝나면 출력이 해당 파일에 기록됩니다(단일 .j 파일은 여러 클래스를 포함할 수 있습니다. 모든 클래스가 디스어셈블되어 동일한 파일에 순서대로 기록됩니다). --out 옵션이 완전히 생략되면 디스어셈블된 클래스가 표준 출력으로 기록됩니다.
위에서 설명한 대로 라운드트립 모드로 디스어셈블하려면 --roundtrip 옵션(또는 짧게 -r)을 전달하십시오.
Krakatau 어셈블러를 사용하면 사람이 읽기 쉬운 텍스트 기반 형식으로 Java 바이트코드를 작성하고 이를 바이너리 Java 클래스파일로 변환할 수 있습니다.
krak2 asm --out temp Krakatau/tests/assembler/good/strictfp.j
개별 .j 파일 또는 전체 jar 파일을 어셈블할 수 있습니다. 입력 파일명이 .jar 또는 .zip으로 끝나면 zip 아카이브로 처리되어 내부의 모든 .j 파일이 어셈블됩니다.
--out 옵션은 출력 위치를 제어합니다. --out 값이 디렉터리이면 출력이 해당 디렉터리 아래의 개별 파일로 배치됩니다. 그렇지 않고 --out 값이 .jar 또는 .zip으로 끝나면 출력이 해당 위치의 단일 zip 파일로 배치됩니다. --out 값이 .class로 끝나면 단일 출력 클래스파일이 해당 파일에 기록됩니다(입력에 여러 클래스가 있는 경우 이 경우 오류가 발생합니다).
v2 디컴파일러는 아직 개발 중입니다. 현재 디컴파일을 위해서는 Krakatau v1을 사용해야 합니다.