diff options
| author | Noa <33094578+coolreader18@users.noreply.github.com> | 2022-01-04 20:40:16 -0600 | 
|---|---|---|
| committer | iximeow <me@iximeow.net> | 2022-01-12 14:41:18 -0800 | 
| commit | 5214a222c24a12adafb3180cbd570bcad0a72a5d (patch) | |
| tree | 5cd9bc8d023d110a1c48417ab5534e32c96ba220 | |
| parent | 65b651155aa1e85bfa505f8c9011ca4b3eba40b2 (diff) | |
Upgrade clap to v3 + switch to derive(clap::Parser)
| -rw-r--r-- | Cargo.lock | 134 | ||||
| -rw-r--r-- | Cargo.toml | 2 | ||||
| -rw-r--r-- | src/main.rs | 222 | 
3 files changed, 232 insertions, 126 deletions
| @@ -3,15 +3,6 @@  version = 3  [[package]] -name = "ansi_term" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" -dependencies = [ - "winapi", -] - -[[package]]  name = "atty"  version = "0.2.14"  source = "registry+https://github.com/rust-lang/crates.io-index" @@ -48,17 +39,32 @@ dependencies = [  [[package]]  name = "clap" -version = "2.34.0" +version = "3.0.4"  source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" +checksum = "d01c9347757e131122b19cd19a05c85805b68c2352a97b623efdc3c295290299"  dependencies = [ - "ansi_term",   "atty",   "bitflags", + "clap_derive", + "indexmap", + "lazy_static", + "os_str_bytes",   "strsim", + "termcolor",   "textwrap", - "unicode-width", - "vec_map", +] + +[[package]] +name = "clap_derive" +version = "3.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "448c8b00367288ad41804ac7a9e0fe58f2324a36901cb5d6b6db58be86d1db8f" +dependencies = [ + "heck", + "proc-macro-error", + "proc-macro2 1.0.36", + "quote 1.0.14", + "syn 1.0.84",  ]  [[package]] @@ -74,6 +80,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index"  checksum = "fed34cd105917e91daa4da6b3728c47b068749d6a62c59811f06ed2ac71d9da7"  [[package]] +name = "hashbrown" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" + +[[package]] +name = "heck" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" + +[[package]]  name = "hermit-abi"  version = "0.1.19"  source = "registry+https://github.com/rust-lang/crates.io-index" @@ -89,6 +107,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"  checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"  [[package]] +name = "indexmap" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc633605454125dec4b66843673f01c7df2b89479b32e0ed634e43a91cff62a5" +dependencies = [ + "autocfg", + "hashbrown", +] + +[[package]]  name = "itertools"  version = "0.10.3"  source = "registry+https://github.com/rust-lang/crates.io-index" @@ -98,12 +126,24 @@ dependencies = [  ]  [[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]]  name = "libc"  version = "0.2.112"  source = "registry+https://github.com/rust-lang/crates.io-index"  checksum = "1b03d17f364a3a042d5e5d46b053bbbf82c92c9430c592dd4c064dc6ee997125"  [[package]] +name = "memchr" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" + +[[package]]  name = "num-traits"  version = "0.2.14"  source = "registry+https://github.com/rust-lang/crates.io-index" @@ -124,6 +164,39 @@ dependencies = [  ]  [[package]] +name = "os_str_bytes" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e22443d1643a904602595ba1cd8f7d896afe56d26712531c5ff73a15b2fbf64" +dependencies = [ + "memchr", +] + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2 1.0.36", + "quote 1.0.14", + "syn 1.0.84", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2 1.0.36", + "quote 1.0.14", + "version_check", +] + +[[package]]  name = "proc-macro2"  version = "0.4.30"  source = "registry+https://github.com/rust-lang/crates.io-index" @@ -184,9 +257,9 @@ dependencies = [  [[package]]  name = "strsim" -version = "0.8.0" +version = "0.10.0"  source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"  [[package]]  name = "syn" @@ -217,19 +290,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index"  checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369"  [[package]] -name = "textwrap" -version = "0.11.0" +name = "termcolor" +version = "1.1.2"  source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" +checksum = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4"  dependencies = [ - "unicode-width", + "winapi-util",  ]  [[package]] -name = "unicode-width" -version = "0.1.9" +name = "textwrap" +version = "0.14.2"  source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973" +checksum = "0066c8d12af8b5acd21e00547c3797fde4e8677254a7ee429176ccebbe93dd80"  [[package]]  name = "unicode-xid" @@ -244,10 +317,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"  checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"  [[package]] -name = "vec_map" -version = "0.8.2" +name = "version_check" +version = "0.9.4"  source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"  [[package]]  name = "winapi" @@ -266,6 +339,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"  checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"  [[package]] +name = "winapi-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +dependencies = [ + "winapi", +] + +[[package]]  name = "winapi-x86_64-pc-windows-gnu"  version = "0.4.0"  source = "registry+https://github.com/rust-lang/crates.io-index" @@ -17,7 +17,7 @@ path = "src/main.rs"  yaxpeax-arch-02 = { package = "yaxpeax-arch", path = "/toy/yaxpeax/yaxpeax-arch/" }  [dependencies] -clap = "2.33" +clap = { version = "3", features = ["derive"] }  hex = "0.4.0"  num-traits = "0.2.10"  itertools = "0.10.1" diff --git a/src/main.rs b/src/main.rs index ab0a0a4..42aa338 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,56 +1,103 @@ -use std::fs::File; -use std::io::{Read, Write}; -use std::{fmt, io}; +use std::io::Write; +use std::{fmt, io, fs}; +use std::str::FromStr; +use std::path::PathBuf; + +use clap::Parser; + +#[derive(Debug)] +enum Architecture { +    X86_64, +    X86_32, +    X86_16, +    IA64, +    AVR, +    ARMv7, +    ARMv7Thumb, +    ARMv8, +    MIPS, +    MSP430, +    PIC17, +    PIC18, +    M16C, +    N6502, +    LC87, +    // PIC24, +    SuperH(yaxpeax_superh::SuperHDecoder), +} + +impl fmt::Display for Architecture { +    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { +        fmt::Debug::fmt(self, f) +    } +} + +impl FromStr for Architecture { +    type Err = &'static str; +    fn from_str(arch_str: &str) -> Result<Self, Self::Err> { +        use Architecture::*; +        let err_str = "possible values: x86_64, x86_32, x86_16, x86:64, x86:32, x86:16, \ +                                        ia64, armv7, armv7-t, armv8, avr, mips, msp430, pic17, pic18, \ +                                        m16c, 6502, lc87, {sh{,2,3,4},j2}[[+-]{be,mmu,fpu,f64,j2}]*"; +        let arch = match arch_str { +            "x86_64" | "x86:64" => X86_64, +            "x86_32" | "x86:32" => X86_32, +            "x86_16" | "x86:16" => X86_16, +            "ia64" => IA64, +            "avr" => AVR, +            "armv7" => ARMv7, +            "armv7-t" => ARMv7Thumb, +            "armv8" => ARMv8, +            "mips" => MIPS, +            "msp430" => MSP430, +            "pic17" => PIC17, +            "pic18" => PIC18, +            "m16c" => M16C, +            "6502" => N6502, +            "lc87" => LC87, +            //        "pic24" => PIC24, +            _ => { +                let seg_idx = arch_str.find(&['+', '-'][..]).unwrap_or(arch_str.len()); +                let (base, features) = arch_str.split_at(seg_idx); +                let decoder = match base { +                    "sh" => yaxpeax_superh::SuperHDecoder::SH1, +                    "sh2" => yaxpeax_superh::SuperHDecoder::SH2, +                    "sh3" => yaxpeax_superh::SuperHDecoder::SH3, +                    "sh4" => yaxpeax_superh::SuperHDecoder::SH4, +                    "j2" => yaxpeax_superh::SuperHDecoder::J2, +                    _ => return Err(err_str), +                }; +                SuperH(parse_superh(decoder, features)) +            } +        }; +        Ok(arch) +    } +} + +#[derive(Parser)] +#[clap(about, version, author)] +struct Args { +    /// architecture to disassemble input as. +    #[clap(short, long, default_value = "x86_64")] +    architecture: Architecture, + +    /// file of bytes to decode +    #[clap(short, long, parse(from_os_str), conflicts_with = "data")] +    file: Option<PathBuf>, + +    /// increased detail when decoding instructions +    #[clap(short, long, parse(from_occurrences))] +    verbose: u8, + +    /// hex bytes to decode by the selected architecture. for example, try -a x86_64 33c0c3 +    #[clap(required_unless_present = "file")] +    data: Option<String>, +}  fn main() { -    use clap::*; -    let _ = include_str!("../Cargo.toml"); -    let app = app_from_crate!() -        .arg( -            Arg::with_name("arch") -                .short("a") -                .long("--architecture") -                .takes_value(true) -                .validator(|a| { -                    if ["x86_64", "x86_32", "x86_16", -                        "x86:64", "x86:32", "x86:16", -                        "ia64", "armv7", "armv7-t","armv8", "avr", "mips", "msp430", -                        "pic17", "pic18", "m16c", "6502", "lc87"].contains(&&a[..]) || -                       (["sh", "sh2", "sh3", "sh4", "j2"].contains( -                             &&a[0..a.find(&['+', '-'][..]).unwrap_or(a.len())]) && -                        a.split(&['+', '-'][..]).skip(1).all( -                            |f| ["be", "mmu", "fpu", "f64", "j2"].contains(&f))) { -                        Ok(()) -                    } else { -                        Err("possible values: x86_64, x86_32, x86_16, x86:64, x86:32, x86:16, \ -                                              ia64, armv7, armv7-t, armv8, avr, mips, msp430, pic17, pic18, \ -                                              m16c, 6502, lc87, {sh{,2,3,4},j2}[[+-]{be,mmu,fpu,f64,j2}]*" -                            .to_string()) -                    } -                }) -                .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").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: Vec<u8> = match matches.value_of("data") { +    let args = Args::parse(); + +    let buf: Vec<u8> = match args.data {          Some(data) => match hex::decode(data) {              Ok(buf) => buf,              Err(e) => { @@ -59,62 +106,39 @@ fn main() {              }          },          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."); +            let name = args.file.unwrap(); +            match fs::read(&name) { +                Ok(v) => v, +                Err(e) => { +                    eprintln!("error reading {}: {}", name.display(), e);                      return;                  }              }          }      }; -    let verbose = matches.occurrences_of("verbose") > 0; +    let verbose = args.verbose > 0;      let printer = Printer { stdout: io::stdout(), verbose }; -    match arch_str { -        "x86_64" | -        "x86:64" => arch_02::decode_input_and_annotate::<yaxpeax_x86::long_mode::Arch>(&buf, &printer), -        "x86_32" | -        "x86:32" => arch_02::decode_input_and_annotate::<yaxpeax_x86::protected_mode::Arch>(&buf, &printer), -        "x86_16" | -        "x86:16" => arch_02::decode_input_and_annotate::<yaxpeax_x86::real_mode::Arch>(&buf, &printer), -        "ia64" => arch_02::decode_input::<yaxpeax_ia64::IA64>(&buf, &printer), -        "avr" => arch_02::decode_input::<yaxpeax_avr::AVR>(&buf, &printer), -        "armv7" => arch_02::decode_input::<yaxpeax_arm::armv7::ARMv7>(&buf, &printer), -        "armv7-t" => arch_02::decode_armv7_thumb(&buf, &printer), -        "armv8" => arch_02::decode_input::<yaxpeax_arm::armv8::a64::ARMv8>(&buf, &printer), -        "mips" => arch_02::decode_input::<yaxpeax_mips::MIPS>(&buf, &printer), -        "msp430" => arch_02::decode_input_and_annotate::<yaxpeax_msp430::MSP430>(&buf, &printer), -        "pic17" => arch_02::decode_input::<yaxpeax_pic17::PIC17>(&buf, &printer), -        "pic18" => arch_02::decode_input::<yaxpeax_pic18::PIC18>(&buf, &printer), -        "m16c" => arch_02::decode_input::<yaxpeax_m16c::M16C>(&buf, &printer), -        "6502" => arch_02::decode_input::<yaxpeax_6502::N6502>(&buf, &printer), -        "lc87" => arch_02::decode_input::<yaxpeax_lc87::LC87>(&buf, &printer), -        //        "pic24" => decode_input::<yaxpeax_pic24::PIC24>(buf), -        other => { -            let seg_idx = arch_str.find(&['+', '-'][..]).unwrap_or(arch_str.len()); -            let decode = |base| arch_02::decode_input_with_decoder::<yaxpeax_superh::SuperH>( -                parse_superh(base, &arch_str[seg_idx..]), &buf, &printer); -            match &arch_str[0..seg_idx] { -                "sh" => decode(yaxpeax_superh::SuperHDecoder::SH1), -                "sh2" => decode(yaxpeax_superh::SuperHDecoder::SH2), -                "sh3" => decode(yaxpeax_superh::SuperHDecoder::SH3), -                "sh4" => decode(yaxpeax_superh::SuperHDecoder::SH4), -                "j2" => decode(yaxpeax_superh::SuperHDecoder::J2), -                _ => println!("unsupported architecture: {}", other), -            } -        } +    use Architecture::*; +    match args.architecture { +        X86_64 => arch_02::decode_input_and_annotate::<yaxpeax_x86::long_mode::Arch>(&buf, &printer), +        X86_32 => arch_02::decode_input_and_annotate::<yaxpeax_x86::protected_mode::Arch>(&buf, &printer), +        X86_16 => arch_02::decode_input_and_annotate::<yaxpeax_x86::real_mode::Arch>(&buf, &printer), +        IA64 => arch_02::decode_input::<yaxpeax_ia64::IA64>(&buf, &printer), +        AVR => arch_02::decode_input::<yaxpeax_avr::AVR>(&buf, &printer), +        ARMv7 => arch_02::decode_input::<yaxpeax_arm::armv7::ARMv7>(&buf, &printer), +        ARMv7Thumb => arch_02::decode_armv7_thumb(&buf, &printer), +        ARMv8 => arch_02::decode_input::<yaxpeax_arm::armv8::a64::ARMv8>(&buf, &printer), +        MIPS => arch_02::decode_input::<yaxpeax_mips::MIPS>(&buf, &printer), +        MSP430 => arch_02::decode_input_and_annotate::<yaxpeax_msp430::MSP430>(&buf, &printer), +        PIC17 => arch_02::decode_input::<yaxpeax_pic17::PIC17>(&buf, &printer), +        PIC18 => arch_02::decode_input::<yaxpeax_pic18::PIC18>(&buf, &printer), +        M16C => arch_02::decode_input::<yaxpeax_m16c::M16C>(&buf, &printer), +        N6502 => arch_02::decode_input::<yaxpeax_6502::N6502>(&buf, &printer), +        LC87 => arch_02::decode_input::<yaxpeax_lc87::LC87>(&buf, &printer), +        //        PIC24 => decode_input::<yaxpeax_pic24::PIC24>(buf), +        SuperH(decoder) => arch_02::decode_input_with_decoder::<yaxpeax_superh::SuperH>(decoder, &buf, &printer),      }  } | 
