Crate yaxpeax_x86[−][src]
Expand description
yaxpeax-x86
, a decoder for x86-family instruction sets
yaxpeax-x86
provides x86 decoders, for 64-, 32-, and 16-bit modes. yaxpeax-x86
also
implements traits defined by yaxpeax_arch
, making it suitable for interchangeable use with
other yaxpeax
-family instruction decoders.
usage
the fastest way to decode an x86 instruction is through amd64::InstDecoder::decode_slice()
:
let decoder = yaxpeax_x86::amd64::InstDecoder::default(); let inst = decoder.decode_slice(&[0x33, 0xc0]).unwrap(); assert_eq!("xor eax, eax", inst.to_string());
instructions, operands, registers, and generally all decoding structures, are in their mode’s repsective submodule:
x86_64
/amd64
decoding is underlong_mode
x86_32
/x86
decoding is underprotected_mode
x86_16
/8086
decoding is underreal_mode
all modes have equivalent data available in a decoded instruction. for example, all modes have
library-friendly Operand
and RegSpec
types:
use yaxpeax_x86::amd64::{InstDecoder, Operand, RegSpec}; let decoder = yaxpeax_x86::amd64::InstDecoder::default(); let inst = decoder.decode_slice(&[0x33, 0x01]).unwrap(); assert_eq!("xor eax, dword [rcx]", inst.to_string()); assert_eq!(Operand::Register(RegSpec::eax()), inst.operand(0)); assert_eq!("eax", inst.operand(0).to_string()); assert_eq!(Operand::RegDeref(RegSpec::rcx()), inst.operand(1)); // an operand in isolation does not know the size of memory it references, if any assert_eq!("[rcx]", inst.operand(1).to_string()); // and for memory operands, the size must be read from the instruction itself: let mem_size: yaxpeax_x86::amd64::MemoryAccessSize = inst.mem_size().unwrap(); assert_eq!("dword", mem_size.size_name()); // `MemoryAccessSize::size_name()` is how its `Display` impl works, as well: assert_eq!("dword", mem_size.to_string());
yaxpeax-x86
can also be used to decode instructions generically through the yaxpeax-arch
traits:
mod decoder { use yaxpeax_arch::{Arch, AddressDisplay, Decoder, Reader, ReaderBuilder}; pub fn decode_stream< 'data, A: yaxpeax_arch::Arch, U: ReaderBuilder<A::Address, A::Word>, >(data: U) where A::Instruction: std::fmt::Display, { let mut reader = ReaderBuilder::read_from(data); let mut address: A::Address = reader.total_offset(); let decoder = A::Decoder::default(); let mut decode_res = decoder.decode(&mut reader); loop { match decode_res { Ok(ref inst) => { println!("{}: {}", address.show(), inst); decode_res = decoder.decode(&mut reader); address = reader.total_offset(); } Err(e) => { println!("{}: decode error: {}", address.show(), e); break; } } } } } use yaxpeax_x86::amd64::{Arch as x86_64}; use yaxpeax_arch::{ReaderBuilder, U8Reader}; let data: &[u8] = &[0x55, 0x33, 0xc0, 0x48, 0x8b, 0x02, 0x5d, 0xc3]; decoder::decode_stream::<x86_64, _>(data);
#![no_std]
yaxpeax-x86
supports no_std
usage. to be built no_std
, yaxpeax-x86
only needs
default-features = false
in the corresponding Cargo.toml
dependency. if formatting is
needed with std
disabled, it can be re-enabled by explicitly requesting the fmt
features
like:
yaxpeax-x86 = { version = "*", default-features = false, features = ["fmt"] }
this is how the .so
and .a
packaging in
ffi/
is performed.
Re-exports
pub use long_mode as amd64;
pub use long_mode::Arch as x86_64;
pub use protected_mode::Arch as x86_32;
pub use real_mode::Arch as x86_16;