/noak

A java bytecode decoding and encoding library written in rust. Mirror of https://gitlab.com/frozo/noak

Primary LanguageRustApache License 2.0Apache-2.0

Noak

A library for reading and writing java class files.

Example

use noak::reader::Class;

let mut class = Class::new(&bytes)?;

println!("Major Version: {}", class.version().major);
println!(" Access Flags: {:?}", class.access_flags()?);
println!("   Class Name: {}", class.this_class_name()?.display()?);

Why should you use noak?

  • Reading:
    • You want to parse class files without losing information.
    • You don't want to parse the entire class file.
    • Any valid class file is accepted by noak. Many invalid class files are accepted as well (this can be useful for reading heavily obfuscated code).
  • Writing:
    • You want to write your own class files (limitations apply; see below).

Why wouldn't you use noak?

Many of these issues are in the process of being resolved, but that may take some time.

  • You want more than just a low-level class file reader and writer.
  • Noak makes heavy use of the type system and macros. This can cause problems with your IDE or make some aspects hard to understand.
  • Documentation is virtually non-existent.
  • The API is very unstable.
  • The code is not heavily tested.
  • Reading:
    • Some code may be repetitive (e.g. retrieving values from the constant pool).
  • Writing:
    • Modifying existing class files can be very tedious.
    • Not every attribute can be written at the moment (related issue)
    • Jumps above 65535 bytes may fail to be written.
    • The builder API isn't flexible enough for your use case.
    • Custom errors are quite restricted.
    • Stack Map Frames are not automatically generated.

Alternatives

This is not an exhaustive list. The statements below may not accurately reflect reality.

Libraries written in Rust:

  • cafebabe
    • Parses the entire file at once.
    • Accesses the constant pool during parsing. No explicit retrieval from the user side required.
  • classreader-rs
    • Parses the entire file at once.
    • Only supports parsing.
    • Does not support any attributes from version 53.0 and above.
    • Does not parse strings containing unpaired surrogates.
  • jbcrs
    • Parses the entire file at once.
    • Only supports parsing.
    • Does not support any attributes from version 53.0 and above.
    • Does not parse files containing UTF-8 constants with unpaired surrogates.
  • frappe/classfile
    • Parses the entire file at once.
    • Only supports parsing.
    • Does not support any attributes from version 53.0 and above.
    • Does not parse files containing UTF-8 constants with surrogates.
  • classfile-rs
    • Seems to be very incomplete.
    • Supports writing as well as parsing.
    • Parses the entire file at once.
    • Reads UTF-8 constants lossily.
  • classfile-parser
    • Seems to be very incomplete.
    • Parses the entire file at once.
    • Only supports parsing.
  • classfmt
    • Seems to be very incomplete.
    • Parses the entire file at once.
    • Only supports parsing.
  • javabc
    • Seems to be very incomplete.
    • Parses the entire file at once.
    • Only supports parsing.

A small fraction of libraries written in languages that are not Rust:

  • ASM (Java)
    • The most comprehensive and best supported class file manipulation and analysis framework.
    • Use this if noak does not suit your requirements and probably even if it does suit them.
  • javassist (Java)
    • A high-level bytecode library.
  • BCEL (Java)

License

This project is licensed under the MIT license.