use hermes_rs::HermesFile;
use std::env;
use std::fs::File;
use std::io;
fn main() {
let args: Vec<String> = env::args().collect();
if args.len() < 2 {
eprintln!("Usage: {} <input_file>", args[0]);
return;
}
let filepath = &args[1];
if !std::path::Path::new(filepath).exists() {
println!("File not found: {}", filepath);
std::process::exit(1);
}
let f = File::open(filepath).expect("no file found");
let mut reader = io::BufReader::new(f);
let hermes_file = HermesFile::deserialize(&mut reader);
println!("# R2 script for Hermes bytecode file: {}", filepath);
println!("# Generated by hermes_rs\n");
println!("# Hermes File Version: {}", hermes_file.header.version);
println!("# File Size: {} bytes", hermes_file.header.file_length);
println!("# Function Count: {}\n", hermes_file.header.function_count);
println!("f hbc.header=0x0");
println!("f hbc.header.size=0x{:x}\n", hermes_file.header.file_length);
println!("# Function flags");
for (i, function_header) in hermes_file.function_headers.iter().enumerate() {
let function_name =
hermes_file.get_string_from_storage_by_index(function_header.func_name() as usize);
let sanitized_name = if function_name.is_empty() {
format!("func_{}", i)
} else {
function_name.replace(|c: char| !c.is_alphanumeric() && c != '_', "_")
};
println!(
"\'f func.hermes.{} {} 0x{:x}",
sanitized_name,
function_header.size(),
function_header.offset()
);
}
println!("\n# String flags");
let strings = hermes_file.get_strings();
for (i, s) in strings.iter().enumerate() {
let sanitized_name = s
.chars()
.map(|c| {
if c.is_ascii_alphanumeric() || c == '_' {
c
} else {
'_'
}
})
.collect::<String>();
let size = s.len();
let offset = hermes_file.string_storage.get(i).unwrap().offset;
let unique_name = format!("{}_{}", sanitized_name, i);
println!("'f str.{} {} 0x{:x}", unique_name, size, offset);
}
}