aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock134
-rw-r--r--Cargo.toml2
-rw-r--r--src/main.rs222
3 files changed, 232 insertions, 126 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 1883a72..81c4755 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -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"
diff --git a/Cargo.toml b/Cargo.toml
index aeb5364..dbb33db 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -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),
}
}