#java-class #class #java #jvm #bytecode

jbcrs

一个用于支持读取和写入Java类文件的库

4个版本

使用旧的Rust 2015

0.1.3 2018年3月14日
0.1.2 2018年2月25日
0.1.1 2018年2月25日
0.1.0 2018年2月25日

#2445 in 解析器实现

无许可

100KB
2.5K SLoC

JBcRs

JBcRs是一个库,用Rust编写,用于支持读取和写入Java类文件。

此库尚未完成,但某些功能已实现

  • 基本解析: 类文件以相当原始的方式解析
    • 您可以访问常量池。名称、描述符等以 u16 表示,必须手动对池进行索引。解析时不会验证索引。
    • 使用bitflags crate解码访问标志,以提供更好的体验。
    • 始终解析属性。这可能会改变,因为它允许攻击者构建无效的调试属性,这些属性在执行代码时没有重要作用。然后解析整个类文件可能不起作用,因为会返回错误。
  • 更多即将到来™。

入门指南

首先,将此库添加到您的Cargo.toml中作为依赖项

[dependencies]
jbcrs = "0.1.0"

现在,您应该选择是否要使用 basicadvanced,但由于 advanced 尚未实现,因此必须使用 basic

基本

我们想从字节数组中解析一个类并打印其版本、访问标志和名称。当然,您可以使用std::fs::File或zip库,但这不是本教程的目的。

use jbcrs::basic;

// You got the bytes from any possible source.
let bytes: &[u8] = [0xCA, 0xFE, 0xBA, 0xBE];

// After parsing the class file,
// you will get the constant pool
// and the class itself.
// You don't have to annotate the types here.
let (constant_pool, class): (basic::Pool, basic::Class) = basic::parse(bytes)
    .expect("could not parse class file");

// Print its major and minor version:
println!("version: {}.{}", class.major_version, class.minor_version);

// Access Flags can be printed human readable
println!("access: {}", class.access_flags);

// Printing the name requires us to use the constant pool.
println!("name: {}", constant_pool.get_class_name(class.name).expect("could not get class name"));

资源

Java虚拟机规范(Java SE 9)

依赖项

~2MB
~47K SLoC