Struct iced_x86::BlockEncoder

source ·
pub struct BlockEncoder { /* private fields */ }
Expand description

Encodes instructions. It can be used to move instructions from one location to another location.

Implementations§

Encodes instructions. Any number of branches can be part of this block. You can use this function to move instructions from one location to another location. If the target of a branch is too far away, it’ll be rewritten to a longer branch. You can disable this by passing in BlockEncoderOptions::DONT_FIX_BRANCHES. If the block has any RIP-relative memory operands, make sure the data isn’t too far away from the new location of the encoded instructions. Every OS should have some API to allocate memory close (+/-2GB) to the original code location.

Errors

Returns an error if it failed to encode one or more instructions.

Arguments
  • bitness: 16, 32, or 64
  • block: All instructions
  • options: Encoder options, see BlockEncoderOptions
Examples
use iced_x86::*;

// je short $-2
// add dh,cl
// sbb r9d,ebx
let bytes = b"\x75\xFC\x00\xCE\x41\x19\xD9";
let decoder = Decoder::with_ip(64, bytes, 0x1234_5678_9ABC_DEF0, DecoderOptions::NONE);
let instructions: Vec<_> = decoder.into_iter().collect();

// orig_rip + 8
let block = InstructionBlock::new(&instructions, 0x1234_5678_9ABC_DEF8);
let bytes = match BlockEncoder::encode(64, block, BlockEncoderOptions::NONE) {
    Err(err) => panic!("Failed: {}", err),
    Ok(result) => result.code_buffer,
};
assert_eq!(bytes, vec![0x75, 0xF4, 0x00, 0xCE, 0x41, 0x19, 0xD9]);
Examples found in repository?
src/code_asm/code_asm_methods.rs (line 1124)
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
	pub fn assemble_options(&mut self, ip: u64, options: u32) -> Result<CodeAssemblerResult, IcedError> {
		if self.prefix_flags != 0 {
			return Err(IcedError::new("Unused prefixes. Did you forget to add an instruction?"));
		}
		if !self.current_label.is_empty() {
			return Err(IcedError::new("Unused label. Did you forget to add an instruction?"));
		}
		if self.defined_anon_label {
			return Err(IcedError::new("Unused anonymous label. Did you forget to add an instruction?"));
		}
		if !self.next_anon_label.is_empty() {
			return Err(IcedError::new("Unused anonymous fwd() label. Did you forget to call anonymous_label()?"));
		}

		let block = InstructionBlock::new(self.instructions(), ip);
		let result = BlockEncoder::encode(self.bitness(), block, options)?;
		Ok(CodeAssemblerResult { inner: result })
	}

Encodes instructions. Any number of branches can be part of this block. You can use this function to move instructions from one location to another location. If the target of a branch is too far away, it’ll be rewritten to a longer branch. You can disable this by passing in BlockEncoderOptions::DONT_FIX_BRANCHES. If the block has any RIP-relative memory operands, make sure the data isn’t too far away from the new location of the encoded instructions. Every OS should have some API to allocate memory close (+/-2GB) to the original code location.

Errors

Returns an error if it failed to encode one or more instructions.

Arguments
  • bitness: 16, 32, or 64
  • blocks: All instructions
  • options: Encoder options, see BlockEncoderOptions
Examples
use iced_x86::*;

// je short $-2
// add dh,cl
// sbb r9d,ebx
let bytes = b"\x75\xFC\x00\xCE\x41\x19\xD9";
let decoder = Decoder::with_ip(64, bytes, 0x1234_5678_9ABC_DEF0, DecoderOptions::NONE);
let instructions1: Vec<_> = decoder.into_iter().collect();

// je short $
let bytes = b"\x75\xFE";
let decoder = Decoder::with_ip(64, bytes, 0x1234_5678, DecoderOptions::NONE);
let instructions2: Vec<_> = decoder.into_iter().collect();

// orig_rip + 8
let block1 = InstructionBlock::new(&instructions1, 0x1234_5678_9ABC_DEF8);
// a new ip
let block2 = InstructionBlock::new(&instructions2, 0x8000_4000_2000_1000);
let bytes = match BlockEncoder::encode_slice(64, &[block1, block2], BlockEncoderOptions::NONE) {
    Err(err) => panic!("Failed: {}", err),
    Ok(result) => result,
};
assert_eq!(bytes.len(), 2);
assert_eq!(bytes[0].code_buffer, vec![0x75, 0xF4, 0x00, 0xCE, 0x41, 0x19, 0xD9]);
assert_eq!(bytes[1].code_buffer, vec![0x75, 0xFE]);
Examples found in repository?
src/block_enc.rs (line 288)
287
288
289
290
291
292
293
294
295
	pub fn encode(bitness: u32, block: InstructionBlock<'_>, options: u32) -> Result<BlockEncoderResult, IcedError> {
		match Self::encode_slice(bitness, &[block], options) {
			Ok(ref mut result_vec) => {
				debug_assert_eq!(result_vec.len(), 1);
				Ok(result_vec.remove(0))
			}
			Err(err) => Err(err),
		}
	}

Auto Trait Implementations§

Blanket Implementations§

Gets the TypeId of self. Read more
Immutably borrows from an owned value. Read more
Mutably borrows from an owned value. Read more

Returns the argument unchanged.

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

The type returned in the event of a conversion error.
Performs the conversion.
The type returned in the event of a conversion error.
Performs the conversion.