~nabijaczleweli/yaxpeax-dis

ac4b68ac02c80416197413ac079353c4b60bb6ec — iximeow 11 months ago 429edb7
allow file inputs, update decoders, add avr

"update decoders" here means bump decoders to yaxpeax-arch 0.0.4 versions. additionally, this pulls in fixes in x86 0.0.11

add avr decoder by @The9P4C!!
3 files changed, 85 insertions(+), 49 deletions(-)

M Cargo.lock
M Cargo.toml
M src/main.rs
M Cargo.lock => Cargo.lock +28 -17
@@ 259,20 259,21 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"

[[package]]
name = "yaxpeax-arch"
version = "0.0.3"
version = "0.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ab52e5031be876437d8db20de2074486ce6a49e3a0809a8e8b291a307ea808a2"
checksum = "2d4d184a208255bb62f2d55c3875ee3fe459f2b8d9190b8427986b91d11ced7f"
dependencies = [
 "num-traits",
 "serde",
 "serde_derive",
 "termion",
]

[[package]]
name = "yaxpeax-arm"
version = "0.0.3"
version = "0.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2562e1dc153928886795f8f3794716ac0e96ed2ef040f8d29e3246f57d823dd3"
checksum = "2bbd9ff5d85124b77a3c251585a72ab7db55af2ef2b178f43501c975005a21ad"
dependencies = [
 "serde",
 "serde_derive",


@@ 280,14 281,24 @@ dependencies = [
]

[[package]]
name = "yaxpeax-avr"
version = "0.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "16a767283270a42006714135ba24b6d0ca6282d802e3bb553569143fea948641"
dependencies = [
 "yaxpeax-arch",
]

[[package]]
name = "yaxpeax-dis"
version = "0.1.1"
version = "0.1.2"
dependencies = [
 "clap",
 "hex",
 "num-traits",
 "yaxpeax-arch",
 "yaxpeax-arm",
 "yaxpeax-avr",
 "yaxpeax-m16c",
 "yaxpeax-mips",
 "yaxpeax-msp430",


@@ 298,9 309,9 @@ dependencies = [

[[package]]
name = "yaxpeax-m16c"
version = "0.0.2"
version = "0.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "00248964a847ea31080732852503377cbef24144226a42693865700312e9b0c1"
checksum = "b521aff3978cf531339f6ed9ad695f7e056ce386000a3df185f67114b6e541fe"
dependencies = [
 "num-traits",
 "serde",


@@ 310,9 321,9 @@ dependencies = [

[[package]]
name = "yaxpeax-mips"
version = "0.0.2"
version = "0.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "522a0f8af9ca110ab99d29071a4f7953eb7025c3698461bd1adc36dc8a03523f"
checksum = "cee69235e33a2ca10d3cf8ee9489f1afc626f74d1de9c35519f2b74c9dbd9a03"
dependencies = [
 "num_enum",
 "termion",


@@ 321,9 332,9 @@ dependencies = [

[[package]]
name = "yaxpeax-msp430"
version = "0.0.3"
version = "0.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8c1885d516b165a9799ff0a02af51263e2198215ea03097a582f41f3efa34259"
checksum = "d556fe4705aaadc1e14375550e6f344976958f930580adf32388c150cb8e1f24"
dependencies = [
 "termion",
 "yaxpeax-arch",


@@ 331,9 342,9 @@ dependencies = [

[[package]]
name = "yaxpeax-pic17"
version = "0.0.2"
version = "0.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "52f7c1a9869cda40d584e0b6356bc94ea7dbb8b64c5756fb268f33134fc5a75d"
checksum = "cb949b4c5d7afb8210cbaa3d1f2153d12bcac9dd81167dc6275f9f0fb243fb98"
dependencies = [
 "termion",
 "yaxpeax-arch",


@@ 341,18 352,18 @@ dependencies = [

[[package]]
name = "yaxpeax-pic18"
version = "0.0.2"
version = "0.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a5695d4bed74eb94a8a06439ed67cb4f7b244121bf56d735e64facb7b5c698b6"
checksum = "3f5a722e1de4671c1cfe46f54ebe21fe3233823e62d8cc33d698f50b5fcf2e19"
dependencies = [
 "yaxpeax-arch",
]

[[package]]
name = "yaxpeax-x86"
version = "0.0.10"
version = "0.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "03c09fe81a0dd37ce551dfe63dd7ee8848abe3fb60a670344e9e5483ecfd5718"
checksum = "b95531fa2a2fa283d3c2fb3476f43e16e6c83e459d6a87d39dded8b656253207"
dependencies = [
 "num-traits",
 "serde",

M Cargo.toml => Cargo.toml +9 -8
@@ 17,12 17,13 @@ hex = "0.4.0"
num-traits = "0.2.10"

# common interfaces for all yaxpeax decoders
yaxpeax-arch = { version = "0.0.3" }
yaxpeax-arch = { version = "0.0.4" }

yaxpeax-arm = { version = "0.0.3" }
yaxpeax-mips = { version = "0.0.2" }
yaxpeax-msp430 = { version = "0.0.3" }
yaxpeax-pic17 = { version = "0.0.2" }
yaxpeax-pic18 = { version = "0.0.2" }
yaxpeax-x86 = { version = "0.0.10" }
yaxpeax-m16c = { version = "0.0.2" }
yaxpeax-arm = { version = "0.0.4" }
yaxpeax-avr = { version = "0.0.2" }
yaxpeax-m16c = { version = "0.0.3" }
yaxpeax-mips = { version = "0.0.3" }
yaxpeax-msp430 = { version = "0.0.5" }
yaxpeax-pic17 = { version = "0.0.3" }
yaxpeax-pic18 = { version = "0.0.3" }
yaxpeax-x86 = { version = "0.0.11" }

M src/main.rs => src/main.rs +48 -24
@@ 4,6 4,8 @@ use clap::*;
use num_traits::identities::Zero;

use std::fmt;
use std::fs::File;
use std::io::Read;

fn main() {
    let _ = include_str!("../Cargo.toml");


@@ 12,39 14,68 @@ fn main() {
             .short("a")
             .long("--architecture")
             .takes_value(true)
             .possible_values(&["x86_64", "x86:32", "armv7", "armv8", "mips", "msp430", "pic17", "pic18", "m16c"])
             .possible_values(&["x86_64", "x86:32", "armv7", "armv8", "avr", "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 buf: Vec<u8> = match matches.value_of("data") {
        Some(data) => {
            match hex::decode(data) {
                Ok(buf) => buf,
                Err(e) => {
                    eprintln!("Invalid input, {}. Expected a sequence of bytes as hex", e);
                    return;
                }
            }
        }
        None => {
            let mut v = Vec::new();
            match matches.value_of("file") {
                Some(name) => {
                    match File::open(name) {
                        Ok(mut f) => {
                            f.read_to_end(&mut v).expect("can read the file");
                            v
                        }
                        Err(e) => {
                            eprintln!("error opening {}: {}", name, e);
                            return;
                        }
                    }
                }
                None => {
                    eprintln!("data must be provided by either an argument consisting of hex bytes, or by the --file argument.");
                    return;
                }
            }
        }
    };
    let verbose = matches.occurrences_of("verbose") > 0;

    match arch_str {
        "x86_64" => decode_input::<yaxpeax_x86::long_mode::Arch>(buf, verbose),
        "x86:32" => decode_input::<yaxpeax_x86::protected_mode::Arch>(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),
        "x86_64" => decode_input::<yaxpeax_x86::long_mode::Arch>(&buf, verbose),
        "x86:32" => decode_input::<yaxpeax_x86::protected_mode::Arch>(&buf, verbose),
        "avr" => decode_input::<yaxpeax_avr::AVR>(&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);


@@ 52,21 83,14 @@ fn main() {
    }
}

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;
        }
    };
fn decode_input<A: Arch>(buf: &[u8], verbose: bool) where A::Instruction: fmt::Display {
    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);
                println!("{:#010x}: {:14}: {}", addr.to_linear(), hex::encode(&buf[addr.to_linear()..][..A::Address::zero().wrapping_offset(inst.len()).to_linear()]), inst);
                if verbose {
                    println!("  {:?}", inst);
                    if !inst.well_defined() {


@@ 75,7 99,7 @@ fn decode_input<A: Arch>(buf: &str, verbose: bool) where A::Instruction: fmt::Di
                }
                addr += inst.len();
            },
            Err(e) => { println!("{:#010x}: {}", addr.to_linear(), e); break; },
            Err(e) => { println!("{:#010x}: {}", addr.to_linear(), e); addr += A::Instruction::min_size(); },
        }
        if addr.to_linear() >= buf.len() {
            break;