use yaxpeax_arch::{AddressBase, Arch, Decoder, Instruction, LengthedInstruction}; use clap::*; use num_traits::identities::Zero; use std::fmt; fn main() { let _ = include_str!("../Cargo.toml"); let app = app_from_crate!() .arg(Arg::with_name("arch") .short("a") .long("--architecture") .takes_value(true) .possible_values(&["x86_64", "armv7", "armv8", "mips", "msp430", "pic17", "pic18", "m16c"]) .help("architecture to disassemble input as.")) /* .arg(Arg::with_name("file") .short("f") .long("file") .takes_value(true) .help("file of bytes to decode")) */ .arg(Arg::with_name("verbose") .short("v") .long("--verbose") .help("increased detail when decoding instructions")) .arg(Arg::with_name("data") .required(true) .help("hex bytes to decode by the selected architecture. for example, try -a x86_64 33c0c3")); let matches = app.get_matches(); let arch_str = matches.value_of("arch").unwrap_or("x86_64"); let buf: &str = matches.value_of("data").unwrap_or(""); let verbose = matches.occurrences_of("verbose") > 0; match arch_str { "x86_64" => decode_input::(buf, verbose), "armv7" => decode_input::(buf, verbose), "armv8" => decode_input::(buf, verbose), "mips" => decode_input::(buf, verbose), "msp430" => decode_input::(buf, verbose), "pic17" => decode_input::(buf, verbose), "pic18" => decode_input::(buf, verbose), "m16c" => decode_input::(buf, verbose), // "pic24" => decode_input::(buf), other => { println!("unsupported architecture: {}", other); } } } fn decode_input(buf: &str, verbose: bool) where A::Instruction: fmt::Display { let buf = match hex::decode(buf) { Ok(buf) => buf, Err(e) => { eprintln!("Invalid input, {}. Expected a sequence of bytes as hex", e); return; } }; let decoder = A::Decoder::default(); let start = A::Address::zero(); let mut addr = start; loop { match decoder.decode(buf[addr.to_linear()..].iter().cloned()) { Ok(inst) => { println!("{:#010x}: {:14}: {}", addr.to_linear(), hex::encode(&buf[addr.to_linear()..][..inst.len().to_linear()]), inst); if verbose { println!(" {:?}", inst); if !inst.well_defined() { println!(" not well-defined"); } } addr += inst.len(); }, Err(e) => { println!("{:#010x}: {}", addr.to_linear(), e); break; }, } if addr.to_linear() >= buf.len() { break; } } }