Java decompiler, assembler, and disassembler
Go to file
Robert Grosse bced9fad41 Improve error handling (#194)
Display error messages manually instead of panicing
Add context to file errors
Display correct file name for output log messages
2023-03-19 17:33:31 -07:00
docs Assembler syntax specification and basic tutorial (#192) 2023-02-26 17:26:06 -08:00
examples Assembler syntax specification and basic tutorial (#192) 2023-02-26 17:26:06 -08:00
src Improve error handling (#194) 2023-03-19 17:33:31 -07:00
.gitignore Improve error handling (#194) 2023-03-19 17:33:31 -07:00
Cargo.toml Improve error handling (#194) 2023-03-19 17:33:31 -07:00
Foo.class Assembler syntax specification and basic tutorial (#192) 2023-02-26 17:26:06 -08:00
LICENSE.TXT Initial v2 assembler and diassembler 2022-10-16 16:51:57 -07:00
README.md Add mention of decompiler and link to v1 to readme 2023-03-12 18:57:12 -07:00
rustfmt.toml Initial v2 assembler and diassembler 2022-10-16 16:51:57 -07:00

Krakatau provides an assembler and disassembler for Java bytecode, which allows you to convert binary classfiles to a human readable text format, make changes, and convert it back to a classfile, even for obfuscated code. You can also create your own classfiles from scratch by writing bytecode manually, and can examine and compare low level details of Java binaries. Unlike javap, the Krakatau disassembler can handle even highly obfuscated code, and the disassembled output can be reassembled into a classfile.

Krakatau also provides a decompiler for converting Java binaries to readable source code. Unlike other decompilers, the Krakatau decompiler was specifically designed for working with obfuscated code and can easily handle tricks that break other decompilers. However, the Krakatau decompiler does not support some Java 8+ features such as lambdas, so it works best on older code.

Krakatau's assembler syntax is mostly a superset of Jasmin syntax with some minor incompatibilities, but unlike Jasmin, Krakatau has full support for the Java 19 bytecode specification and even supports some undocumented features found in old versions of the JVM. For an overview of the assembler syntax, see the tutorial or complete specification.

Installation

First, you will need to install Rust and Cargo. Then clone this repo and run cargo build --release. This will produce a binary in target/release/krak2, which you can call directly, add to PATH, symlink, etc.

Disassembly

The disassembler has two modes: default and roundtrip. The default mode is optimized for readability and ease of modification of the resulting assembly files. When the output is reassembled, it will result in classfiles that are equivalent in behavior to the original from the perspective of the JVM specification, but not necessarily bit for bit identical (for example, the constant pool entries may be reordered). Roundtrip mode produces output that will reassemble into classfiles that are bit for bit identical to the original, but this means that the assembly files preserve low level encoding information that makes them harder to read, such as the exact order of constant pool entries. It is recommended to use roundtrip mode when working with code that relies on non-standard attributes, such as CLDC code or Scala code.

Example usage:

krak2 dis --out temp RecordTest.class

krak2 dis --out disassembled.zip --roundtrip r0lling-challenge.jar

You can either disassemble an individual classfile or an entire jar file. If the input filename ends in .jar or .zip, it will be treated as a jar file.

The --out option controls the output location. If it ends in .jar or .zip, the output will be placed in a single zipfile at that location. If it ends with .j or .class, output will be written to that file. Otherwise, it will be treated as a directory name and the output will be placed in individual files under that directory.

To disassemble in roundtrip mode as described above, pass the --roundtrip option (or -r for short).

Assembly

The Krakatau assembler allows you to write Java bytecode in a human friendly text based format and convert it into binary Java classfiles.

krak2 asm --out temp Krakatau/tests/assembler/good/strictfp.j

krak2 asm --out alltests.jar -r Krakatau/tests/decompiler/source/

You can either assemble an individual .j file or an entire jar file. If the input filename ends in .jar or .zip, it will be treated as a zip archive and every .j file inside will be assembled.

The --out option controls the output location. If it ends in .jar or .zip, the output will be placed in a single zipfile at that location. If it ends with .j or .class, output will be written to that file. Otherwise, it will be treated as a directory name and the output will be placed in individual files under that directory.

Decompilation

The v2 decompiler is still a work in progress. For decompilation, you currently need to use Krakatau v1.