Decoder¶
- class iced_x86.Decoder(bitness, data, options=0, ip=0)¶
Decodes 16/32/64-bit x86 instructions
- Parameters:
bitness (int) – 16, 32 or 64
data (bytes, bytearray) – Data to decode. For best PERF, use
bytessince it’s immutable and nothing gets copied.options (
DecoderOptions) – (default =DecoderOptions.NONE) Decoder options, eg.DecoderOptions.NO_INVALID_CHECK|DecoderOptions.AMDip (int) – (
u64) (default =0)RIPvalue
- Raises:
ValueError – If bitness is invalid
TypeError – If data is not a supported type
Examples:
from iced_x86 import * data = b"\x86\x64\x32\x16\xF0\xF2\x83\x00\x5A\x62\xC1\xFE\xCB\x6F\xD3" decoder = Decoder(64, data, ip=0x1234_5678) # The decoder is iterable for instr in decoder: print(f"Decoded: IP=0x{instr.ip:X}: {instr}")
Output:
Decoded: IP=0x12345678: xchg ah,[rdx+rsi+16h] Decoded: IP=0x1234567C: xacquire lock add dword ptr [rax],5Ah Decoded: IP=0x12345681: vmovdqu64 zmm18{k3}{z},zmm11from iced_x86 import * # xchg ah,[rdx+rsi+16h] # xacquire lock add dword ptr [rax],5Ah # vmovdqu64 zmm18{k3}{z},zmm11 data = b"\x86\x64\x32\x16\xF0\xF2\x83\x00\x5A\x62\xC1\xFE\xCB\x6F\xD3" decoder = Decoder(64, data, ip=0x1234_5678) instr1 = decoder.decode() assert instr1.code == Code.XCHG_RM8_R8 assert instr1.mnemonic == Mnemonic.XCHG assert instr1.len == 4 instr2 = decoder.decode() assert instr2.code == Code.ADD_RM32_IMM8 assert instr2.mnemonic == Mnemonic.ADD assert instr2.len == 5 instr3 = decoder.decode() assert instr3.code == Code.EVEX_VMOVDQU64_ZMM_K1Z_ZMMM512 assert instr3.mnemonic == Mnemonic.VMOVDQU64 assert instr3.len == 6
It’s sometimes useful to decode some invalid instructions, eg.
lock add esi,ecx. Pass inDecoderOptions.NO_INVALID_CHECKto the constructor and the decoder will decode some invalid encodings.from iced_x86 import * # lock add esi,ecx # lock not allowed data = b"\xF0\x01\xCE" decoder = Decoder(64, data, ip=0x1234_5678) instr = decoder.decode() assert instr.code == Code.INVALID # We want to decode some instructions with invalid encodings decoder = Decoder(64, data, DecoderOptions.NO_INVALID_CHECK, 0x1234_5678) instr = decoder.decode() assert instr.code == Code.ADD_RM32_R32 assert instr.has_lock_prefix
- can_decode¶
Returns
Trueif 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
Decoder.positionandDecoder.max_position.It’s not required to call this method. If this method returns
False, thenDecoder.decode_outandDecoder.decodewill return an instruction whoseInstruction.code==Code.INVALID.Examples:
from iced_x86 import * # nop and an incomplete instruction data = b"\x90\xF3\x0F" decoder = Decoder(64, data, ip=0x1234_5678) # 3 bytes left to read assert decoder.can_decode instr = decoder.decode() assert instr.code == Code.NOPD # 2 bytes left to read assert decoder.can_decode instr = decoder.decode() # Not enough bytes left to decode a full instruction assert decoder.last_error == DecoderError.NO_MORE_BYTES assert instr.code == Code.INVALID assert not instr assert instr.is_invalid # 0 bytes left to read assert not decoder.can_decode
- Type:
- decode()¶
Decodes and returns the next instruction.
See also
Decoder.decode_outwhich avoids copying the decoded instruction to the caller’s return variable. See alsoDecoder.last_error.- Returns:
The next instruction
- Return type:
Examples:
from iced_x86 import * # xrelease lock add [rax],ebx data = b"\xF0\xF3\x01\x18" decoder = Decoder(64, data, ip=0x1234_5678) instr = decoder.decode() assert instr.code == Code.ADD_RM32_R32 assert instr.mnemonic == Mnemonic.ADD assert instr.len == 4 assert instr.op_count == 2 assert instr.op0_kind == OpKind.MEMORY assert instr.memory_base == Register.RAX assert instr.memory_index == Register.NONE assert instr.memory_index_scale == 1 assert instr.memory_displacement == 0 assert instr.memory_segment == Register.DS assert instr.segment_prefix == Register.NONE assert instr.memory_size == MemorySize.UINT32 assert instr.op1_kind == OpKind.REGISTER assert instr.op1_register == Register.EBX assert instr.has_lock_prefix assert instr.has_xrelease_prefix
- decode_out(instruction)¶
Decodes the next instruction.
The difference between this method and
Decoder.decodeis that this method doesn’t need to allocate a new instruction since it overwrites the input instruction.See also
Decoder.last_error.- Parameters:
instruction (
Instruction) – Updated with the decoded instruction.
Examples:
from iced_x86 import * # xrelease lock add [rax],ebx data = b"\xF0\xF3\x01\x18" decoder = Decoder(64, data, ip=0x1234_5678) instr = Instruction() decoder.decode_out(instr) assert instr.code == Code.ADD_RM32_R32 assert instr.mnemonic == Mnemonic.ADD assert instr.len == 4 assert instr.op_count == 2 assert instr.op0_kind == OpKind.MEMORY assert instr.memory_base == Register.RAX assert instr.memory_index == Register.NONE assert instr.memory_index_scale == 1 assert instr.memory_displacement == 0 assert instr.memory_segment == Register.DS assert instr.segment_prefix == Register.NONE assert instr.memory_size == MemorySize.UINT32 assert instr.op1_kind == OpKind.REGISTER assert instr.op1_register == Register.EBX assert instr.has_lock_prefix assert instr.has_xrelease_prefix
- get_constant_offsets(instruction)¶
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.
- Parameters:
instruction (
Instruction) – The latest instruction that was decoded by this decoder- Returns:
Offsets and sizes of immediates
- Return type:
Examples:
from iced_x86 import * # nop # xor dword ptr [rax-5AA5EDCCh],5Ah # 00 01 02 03 04 05 06 # \opc\mrm\displacement___\imm data = b"\x90\x83\xB3\x34\x12\x5A\xA5\x5A" decoder = Decoder(64, data, ip=0x1234_5678) assert decoder.decode().code == Code.NOPD instr = decoder.decode() co = decoder.get_constant_offsets(instr) assert co.has_displacement assert co.displacement_offset == 2 assert co.displacement_size == 4 assert co.has_immediate assert co.immediate_offset == 6 assert co.immediate_size == 1 # It's not an instruction with two immediates (e.g. enter) assert not co.has_immediate2 assert co.immediate_offset2 == 0 assert co.immediate_size2 == 0
- ip¶
(
u64) The currentIP/EIP/RIPvalue, see alsoDecoder.positionNote
The setter only updates the IP value, it does not change the data position, use the
Decoder.positionsetter to change the position.- Type:
- last_error¶
Gets the last decoder error (a
DecoderErrorenum value).Unless you need to know the reason it failed, it’s better to check
Instruction.is_invalidorif not instruction:.- Type:
- max_position¶
(
usize) Gets the max value that can be written toDecoder.position.This is the size of the data that gets decoded to instructions and it’s the length of the data that was passed to the constructor.
- Type:
- position¶
(
usize) The current data position, which is the index into the data passed to the constructor.This value is always <=
Decoder.max_position. WhenDecoder.position==Decoder.max_position, it’s not possible to decode more instructions andDecoder.can_decodereturnsFalse.- Raises:
ValueError – If the new position is invalid.
Examples:
from iced_x86 import * # nop and pause data = b"\x90\xF3\x90" decoder = Decoder(64, data, ip=0x1234_5678) assert decoder.position == 0 assert decoder.max_position == 3 instr = decoder.decode() assert decoder.position == 1 assert instr.code == Code.NOPD instr = decoder.decode() assert decoder.position == 3 assert instr.code == Code.PAUSE # Start all over again decoder.position = 0 decoder.ip = 0x1234_5678 assert decoder.position == 0 assert decoder.decode().code == Code.NOPD assert decoder.decode().code == Code.PAUSE assert decoder.position == 3
- Type: