1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
|
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::<yaxpeax_x86::x86_64>(buf, verbose),
"armv7" => decode_input::<yaxpeax_arm::armv7::ARMv7>(buf, verbose),
"armv8" => decode_input::<yaxpeax_arm::armv8::a64::ARMv8>(buf, verbose),
"mips" => decode_input::<yaxpeax_mips::MIPS>(buf, verbose),
"msp430" => decode_input::<yaxpeax_msp430::MSP430>(buf, verbose),
"pic17" => decode_input::<yaxpeax_pic17::PIC17>(buf, verbose),
"pic18" => decode_input::<yaxpeax_pic18::PIC18>(buf, verbose),
"m16c" => decode_input::<yaxpeax_m16c::M16C>(buf, verbose),
// "pic24" => decode_input::<yaxpeax_pic24::PIC24>(buf),
other => {
println!("unsupported architecture: {}", other);
}
}
}
fn decode_input<A: Arch>(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;
}
}
}
|