Struct iced_x86::Decoder[][src]

pub struct Decoder<'a> { /* fields omitted */ }

Decodes 16/32/64-bit x86 instructions

Implementations

impl<'a> Decoder<'a>[src]

#[must_use]pub fn new(bitness: u32, data: &'a [u8], options: u32) -> Decoder<'a>[src]

Creates a decoder

Panics

Panics if bitness is not one of 16, 32, 64.

Arguments

  • bitness: 16, 32 or 64
  • data: Data to decode
  • options: Decoder options, 0 or eg. DecoderOptions::NO_INVALID_CHECK | DecoderOptions::AMD

Examples

use iced_x86::*;

// xchg ah,[rdx+rsi+16h]
// xacquire lock add dword ptr [rax],5Ah
// vmovdqu64 zmm18{k3}{z},zmm11
let bytes = b"\x86\x64\x32\x16\xF0\xF2\x83\x00\x5A\x62\xC1\xFE\xCB\x6F\xD3";
let mut decoder = Decoder::new(64, bytes, DecoderOptions::NONE);
decoder.set_ip(0x1234_5678);

let instr1 = decoder.decode();
assert_eq!(instr1.code(), Code::Xchg_rm8_r8);
assert_eq!(instr1.mnemonic(), Mnemonic::Xchg);
assert_eq!(instr1.len(), 4);

let instr2 = decoder.decode();
assert_eq!(instr2.code(), Code::Add_rm32_imm8);
assert_eq!(instr2.mnemonic(), Mnemonic::Add);
assert_eq!(instr2.len(), 5);

let instr3 = decoder.decode();
assert_eq!(instr3.code(), Code::EVEX_Vmovdqu64_zmm_k1z_zmmm512);
assert_eq!(instr3.mnemonic(), Mnemonic::Vmovdqu64);
assert_eq!(instr3.len(), 6);

It’s sometimes useful to decode some invalid instructions, eg. lock add esi,ecx. Pass in DecoderOptions::NO_INVALID_CHECK to the constructor and the decoder will decode some invalid encodings.

use iced_x86::*;

// lock add esi,ecx   ; lock not allowed
let bytes = b"\xF0\x01\xCE";
let mut decoder = Decoder::new(64, bytes, DecoderOptions::NONE);
decoder.set_ip(0x1234_5678);
let instr = decoder.decode();
assert_eq!(instr.code(), Code::INVALID);

// We want to decode some instructions with invalid encodings
let mut decoder = Decoder::new(64, bytes, DecoderOptions::NO_INVALID_CHECK);
decoder.set_ip(0x1234_5678);
let instr = decoder.decode();
assert_eq!(instr.code(), Code::Add_rm32_r32);
assert!(instr.has_lock_prefix());

#[must_use]pub fn with_ip(
    bitness: u32,
    data: &'a [u8],
    ip: u64,
    options: u32
) -> Decoder<'a>
[src]

Creates a decoder

Panics

Panics if bitness is not one of 16, 32, 64.

Arguments

  • bitness: 16, 32 or 64
  • data: Data to decode
  • ip: RIP value
  • options: Decoder options, 0 or eg. DecoderOptions::NO_INVALID_CHECK | DecoderOptions::AMD

Examples

use iced_x86::*;

// xchg ah,[rdx+rsi+16h]
// xacquire lock add dword ptr [rax],5Ah
// vmovdqu64 zmm18{k3}{z},zmm11
let bytes = b"\x86\x64\x32\x16\xF0\xF2\x83\x00\x5A\x62\xC1\xFE\xCB\x6F\xD3";
let mut decoder = Decoder::with_ip(64, bytes, 0x1234_5678, DecoderOptions::NONE);

let instr1 = decoder.decode();
assert_eq!(instr1.code(), Code::Xchg_rm8_r8);
assert_eq!(instr1.mnemonic(), Mnemonic::Xchg);
assert_eq!(instr1.len(), 4);

let instr2 = decoder.decode();
assert_eq!(instr2.code(), Code::Add_rm32_imm8);
assert_eq!(instr2.mnemonic(), Mnemonic::Add);
assert_eq!(instr2.len(), 5);

let instr3 = decoder.decode();
assert_eq!(instr3.code(), Code::EVEX_Vmovdqu64_zmm_k1z_zmmm512);
assert_eq!(instr3.mnemonic(), Mnemonic::Vmovdqu64);
assert_eq!(instr3.len(), 6);

It’s sometimes useful to decode some invalid instructions, eg. lock add esi,ecx. Pass in DecoderOptions::NO_INVALID_CHECK to the constructor and the decoder will decode some invalid encodings.

use iced_x86::*;

// lock add esi,ecx   ; lock not allowed
let bytes = b"\xF0\x01\xCE";
let mut decoder = Decoder::with_ip(64, bytes, 0x1234_5678, DecoderOptions::NONE);
let instr = decoder.decode();
assert_eq!(instr.code(), Code::INVALID);

// We want to decode some instructions with invalid encodings
let mut decoder = Decoder::with_ip(64, bytes, 0x1234_5678, DecoderOptions::NO_INVALID_CHECK);
let instr = decoder.decode();
assert_eq!(instr.code(), Code::Add_rm32_r32);
assert!(instr.has_lock_prefix());

pub fn try_new(
    bitness: u32,
    data: &'a [u8],
    options: u32
) -> Result<Decoder<'a>, IcedError>
[src]

Creates a decoder

Errors

Fails if bitness is not one of 16, 32, 64.

Arguments

  • bitness: 16, 32 or 64
  • data: Data to decode
  • options: Decoder options, 0 or eg. DecoderOptions::NO_INVALID_CHECK | DecoderOptions::AMD

Examples

use iced_x86::*;

// xchg ah,[rdx+rsi+16h]
// xacquire lock add dword ptr [rax],5Ah
// vmovdqu64 zmm18{k3}{z},zmm11
let bytes = b"\x86\x64\x32\x16\xF0\xF2\x83\x00\x5A\x62\xC1\xFE\xCB\x6F\xD3";
let mut decoder = Decoder::try_new(64, bytes, DecoderOptions::NONE).unwrap();
decoder.set_ip(0x1234_5678);

let instr1 = decoder.decode();
assert_eq!(instr1.code(), Code::Xchg_rm8_r8);
assert_eq!(instr1.mnemonic(), Mnemonic::Xchg);
assert_eq!(instr1.len(), 4);

let instr2 = decoder.decode();
assert_eq!(instr2.code(), Code::Add_rm32_imm8);
assert_eq!(instr2.mnemonic(), Mnemonic::Add);
assert_eq!(instr2.len(), 5);

let instr3 = decoder.decode();
assert_eq!(instr3.code(), Code::EVEX_Vmovdqu64_zmm_k1z_zmmm512);
assert_eq!(instr3.mnemonic(), Mnemonic::Vmovdqu64);
assert_eq!(instr3.len(), 6);

It’s sometimes useful to decode some invalid instructions, eg. lock add esi,ecx. Pass in DecoderOptions::NO_INVALID_CHECK to the constructor and the decoder will decode some invalid encodings.

use iced_x86::*;

// lock add esi,ecx   ; lock not allowed
let bytes = b"\xF0\x01\xCE";
let mut decoder = Decoder::try_new(64, bytes, DecoderOptions::NONE).unwrap();
decoder.set_ip(0x1234_5678);
let instr = decoder.decode();
assert_eq!(instr.code(), Code::INVALID);

// We want to decode some instructions with invalid encodings
let mut decoder = Decoder::try_new(64, bytes, DecoderOptions::NO_INVALID_CHECK).unwrap();
decoder.set_ip(0x1234_5678);
let instr = decoder.decode();
assert_eq!(instr.code(), Code::Add_rm32_r32);
assert!(instr.has_lock_prefix());

pub fn try_with_ip(
    bitness: u32,
    data: &'a [u8],
    ip: u64,
    options: u32
) -> Result<Decoder<'a>, IcedError>
[src]

Creates a decoder

Errors

Fails if bitness is not one of 16, 32, 64.

Arguments

  • bitness: 16, 32 or 64
  • data: Data to decode
  • ip: RIP value
  • options: Decoder options, 0 or eg. DecoderOptions::NO_INVALID_CHECK | DecoderOptions::AMD

Examples

use iced_x86::*;

// xchg ah,[rdx+rsi+16h]
// xacquire lock add dword ptr [rax],5Ah
// vmovdqu64 zmm18{k3}{z},zmm11
let bytes = b"\x86\x64\x32\x16\xF0\xF2\x83\x00\x5A\x62\xC1\xFE\xCB\x6F\xD3";
let mut decoder = Decoder::try_with_ip(64, bytes, 0x1234_5678, DecoderOptions::NONE).unwrap();

let instr1 = decoder.decode();
assert_eq!(instr1.code(), Code::Xchg_rm8_r8);
assert_eq!(instr1.mnemonic(), Mnemonic::Xchg);
assert_eq!(instr1.len(), 4);

let instr2 = decoder.decode();
assert_eq!(instr2.code(), Code::Add_rm32_imm8);
assert_eq!(instr2.mnemonic(), Mnemonic::Add);
assert_eq!(instr2.len(), 5);

let instr3 = decoder.decode();
assert_eq!(instr3.code(), Code::EVEX_Vmovdqu64_zmm_k1z_zmmm512);
assert_eq!(instr3.mnemonic(), Mnemonic::Vmovdqu64);
assert_eq!(instr3.len(), 6);

It’s sometimes useful to decode some invalid instructions, eg. lock add esi,ecx. Pass in DecoderOptions::NO_INVALID_CHECK to the constructor and the decoder will decode some invalid encodings.

use iced_x86::*;

// lock add esi,ecx   ; lock not allowed
let bytes = b"\xF0\x01\xCE";
let mut decoder = Decoder::try_with_ip(64, bytes, 0x1234_5678, DecoderOptions::NONE).unwrap();
let instr = decoder.decode();
assert_eq!(instr.code(), Code::INVALID);

// We want to decode some instructions with invalid encodings
let mut decoder = Decoder::try_with_ip(64, bytes, 0x1234_5678, DecoderOptions::NO_INVALID_CHECK).unwrap();
let instr = decoder.decode();
assert_eq!(instr.code(), Code::Add_rm32_r32);
assert!(instr.has_lock_prefix());

#[must_use]pub fn ip(&self) -> u64[src]

Gets the current IP/EIP/RIP value, see also position()

pub fn set_ip(&mut self, new_value: u64)[src]

Sets the current IP/EIP/RIP value, see also try_set_position()

This method only updates the IP value, it does not change the data position, use try_set_position() to change the position.

Arguments

  • new_value: New IP

#[must_use]pub fn bitness(&self) -> u32[src]

Gets the bitness (16, 32 or 64)

#[must_use]pub fn max_position(&self) -> usize[src]

Gets the max value that can be passed to try_set_position(). This is the size of the data that gets decoded to instructions and it’s the length of the slice that was passed to the constructor.

#[must_use]pub fn position(&self) -> usize[src]

Gets the current data position. This value is always <= max_position(). When position() == max_position(), it’s not possible to decode more instructions and can_decode() returns false.

pub fn set_position(&mut self, new_pos: usize)[src]

👎 Deprecated since 1.11.0:

This method can panic, use try_set_position() instead

Sets the current data position, which is the index into the data passed to the constructor. This value is always <= max_position()

Panics

Panics if the new position is invalid.

Arguments

Examples

use iced_x86::*;

// nop and pause
let bytes = b"\x90\xF3\x90";
let mut decoder = Decoder::with_ip(64, bytes, 0x1234_5678, DecoderOptions::NONE);

assert_eq!(decoder.position(), 0);
assert_eq!(decoder.max_position(), 3);
let instr = decoder.decode();
assert_eq!(decoder.position(), 1);
assert_eq!(instr.code(), Code::Nopd);

let instr = decoder.decode();
assert_eq!(decoder.position(), 3);
assert_eq!(instr.code(), Code::Pause);

// Start all over again
decoder.set_position(0);
decoder.set_ip(0x1234_5678);
assert_eq!(decoder.position(), 0);
assert_eq!(decoder.decode().code(), Code::Nopd);
assert_eq!(decoder.decode().code(), Code::Pause);
assert_eq!(decoder.position(), 3);

pub fn try_set_position(&mut self, new_pos: usize) -> Result<(), IcedError>[src]

Sets the current data position, which is the index into the data passed to the constructor. This value is always <= max_position()

Errors

Fails if the new position is invalid.

Arguments

Examples

use iced_x86::*;

// nop and pause
let bytes = b"\x90\xF3\x90";
let mut decoder = Decoder::with_ip(64, bytes, 0x1234_5678, DecoderOptions::NONE);

assert_eq!(decoder.position(), 0);
assert_eq!(decoder.max_position(), 3);
let instr = decoder.decode();
assert_eq!(decoder.position(), 1);
assert_eq!(instr.code(), Code::Nopd);

let instr = decoder.decode();
assert_eq!(decoder.position(), 3);
assert_eq!(instr.code(), Code::Pause);

// Start all over again
decoder.try_set_position(0).unwrap();
decoder.set_ip(0x1234_5678);
assert_eq!(decoder.position(), 0);
assert_eq!(decoder.decode().code(), Code::Nopd);
assert_eq!(decoder.decode().code(), Code::Pause);
assert_eq!(decoder.position(), 3);

#[must_use]pub fn can_decode(&self) -> bool[src]

Returns true if there’s at least one more byte to decode. It doesn’t verify that the next instruction is valid, it only checks if there’s at least one more byte to read. See also position() and max_position()

It’s not required to call this method. If this method returns false, then decode_out() and decode() will return an instruction whose code() == Code::INVALID.

Examples

use iced_x86::*;

// nop and an incomplete instruction
let bytes = b"\x90\xF3\x0F";
let mut decoder = Decoder::with_ip(64, bytes, 0x1234_5678, DecoderOptions::NONE);

// 3 bytes left to read
assert!(decoder.can_decode());
let instr = decoder.decode();
assert_eq!(instr.code(), Code::Nopd);

// 2 bytes left to read
assert!(decoder.can_decode());
let instr = decoder.decode();
// Not enough bytes left to decode a full instruction
assert_eq!(instr.code(), Code::INVALID);

// 0 bytes left to read
assert!(!decoder.can_decode());

pub fn iter<'b>(&'b mut self) -> DecoderIter<'a, 'b>[src]

Returns an iterator that borrows this instance to decode instructions until there’s no more data to decode, i.e., until can_decode() returns false.

Examples

use iced_x86::*;

// nop and pause
let bytes = b"\x90\xF3\x90";
let mut decoder = Decoder::with_ip(64, bytes, 0x1234_5678, DecoderOptions::NONE);

let mut iter = decoder.iter();
assert_eq!(iter.next().unwrap().code(), Code::Nopd);
assert_eq!(iter.next().unwrap().code(), Code::Pause);
assert!(iter.next().is_none());

For loop

use iced_x86::*;

let bytes = b"\x90\xF3\x90";
let mut decoder = Decoder::with_ip(64, bytes, 0x1234_5678, DecoderOptions::NONE);

for instr in &mut decoder { // or decoder.iter()
    println!("code: {:?}", instr.code());
}

#[must_use]pub fn last_error(&self) -> DecoderError[src]

Gets the last decoder error. Unless you need to know the reason it failed, it’s better to check instruction.is_invalid().

#[must_use]pub fn decode(&mut self) -> Instruction[src]

Decodes and returns the next instruction, see also decode_out(&mut Instruction) which avoids copying the decoded instruction to the caller’s return variable. See also last_error().

Examples

use iced_x86::*;

// xrelease lock add [rax],ebx
let bytes = b"\xF0\xF3\x01\x18";
let mut decoder = Decoder::with_ip(64, bytes, 0x1234_5678, DecoderOptions::NONE);
let instr = decoder.decode();

assert_eq!(instr.code(), Code::Add_rm32_r32);
assert_eq!(instr.mnemonic(), Mnemonic::Add);
assert_eq!(instr.len(), 4);
assert_eq!(instr.op_count(), 2);

assert_eq!(instr.op0_kind(), OpKind::Memory);
assert_eq!(instr.memory_base(), Register::RAX);
assert_eq!(instr.memory_index(), Register::None);
assert_eq!(instr.memory_index_scale(), 1);
assert_eq!(instr.memory_displacement64(), 0);
assert_eq!(instr.memory_segment(), Register::DS);
assert_eq!(instr.segment_prefix(), Register::None);
assert_eq!(instr.memory_size(), MemorySize::UInt32);

assert_eq!(instr.op1_kind(), OpKind::Register);
assert_eq!(instr.op1_register(), Register::EBX);

assert!(instr.has_lock_prefix());
assert!(instr.has_xrelease_prefix());

pub fn decode_out(&mut self, instruction: &mut Instruction)[src]

Decodes the next instruction. The difference between this method and decode() is that this method doesn’t need to copy the result to the caller’s return variable (saves 40 bytes of copying). See also last_error().

Arguments

  • instruction: Updated with the decoded instruction. All fields are initialized (it’s an out argument)

Examples

use iced_x86::*;

// xrelease lock add [rax],ebx
let bytes = b"\xF0\xF3\x01\x18";
let mut decoder = Decoder::with_ip(64, bytes, 0x1234_5678, DecoderOptions::NONE);
let mut instr = Instruction::default();
decoder.decode_out(&mut instr);

assert_eq!(instr.code(), Code::Add_rm32_r32);
assert_eq!(instr.mnemonic(), Mnemonic::Add);
assert_eq!(instr.len(), 4);
assert_eq!(instr.op_count(), 2);

assert_eq!(instr.op0_kind(), OpKind::Memory);
assert_eq!(instr.memory_base(), Register::RAX);
assert_eq!(instr.memory_index(), Register::None);
assert_eq!(instr.memory_index_scale(), 1);
assert_eq!(instr.memory_displacement64(), 0);
assert_eq!(instr.memory_segment(), Register::DS);
assert_eq!(instr.segment_prefix(), Register::None);
assert_eq!(instr.memory_size(), MemorySize::UInt32);

assert_eq!(instr.op1_kind(), OpKind::Register);
assert_eq!(instr.op1_register(), Register::EBX);

assert!(instr.has_lock_prefix());
assert!(instr.has_xrelease_prefix());

#[must_use]pub fn get_constant_offsets(&self, instruction: &Instruction) -> ConstantOffsets[src]

Gets the offsets of the constants (memory displacement and immediate) in the decoded instruction. The caller can check if there are any relocations at those addresses.

Arguments

  • instruction: The latest instruction that was decoded by this decoder

Examples

use iced_x86::*;

// nop
// xor dword ptr [rax-5AA5EDCCh],5Ah
//                  00  01  02  03  04  05  06
//                \opc\mrm\displacement___\imm
let bytes = b"\x90\x83\xB3\x34\x12\x5A\xA5\x5A";
let mut decoder = Decoder::with_ip(64, bytes, 0x1234_5678, DecoderOptions::NONE);
assert_eq!(decoder.decode().code(), Code::Nopd);
let instr = decoder.decode();
let co = decoder.get_constant_offsets(&instr);

assert!(co.has_displacement());
assert_eq!(co.displacement_offset(), 2);
assert_eq!(co.displacement_size(), 4);
assert!(co.has_immediate());
assert_eq!(co.immediate_offset(), 6);
assert_eq!(co.immediate_size(), 1);
// It's not an instruction with two immediates (e.g. enter)
assert!(!co.has_immediate2());
assert_eq!(co.immediate_offset2(), 0);
assert_eq!(co.immediate_size2(), 0);

Trait Implementations

impl<'a> IntoIterator for Decoder<'a>[src]

type Item = Instruction

The type of the elements being iterated over.

type IntoIter = DecoderIntoIter<'a>

Which kind of iterator are we turning this into?

impl<'a, 'b> IntoIterator for &'b mut Decoder<'a>[src]

type Item = Instruction

The type of the elements being iterated over.

type IntoIter = DecoderIter<'a, 'b>

Which kind of iterator are we turning this into?

Auto Trait Implementations

impl<'a> RefUnwindSafe for Decoder<'a>

impl<'a> !Send for Decoder<'a>

impl<'a> !Sync for Decoder<'a>

impl<'a> Unpin for Decoder<'a>

impl<'a> UnwindSafe for Decoder<'a>

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.