Decoder

class iced_x86.Decoder(bitness, data, options=0, ip=0)

Decodes 16/32/64-bit x86 instructions

Parameters:
Raises:

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},zmm11
from 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 in DecoderOptions.NO_INVALID_CHECK to 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
bitness

Gets the bitness (16, 32 or 64)

Type:

int

can_decode

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 Decoder.position and Decoder.max_position.

It’s not required to call this method. If this method returns False, then Decoder.decode_out and Decoder.decode will return an instruction whose Instruction.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:

bool

decode()

Decodes and returns the next instruction.

See also Decoder.decode_out which avoids copying the decoded instruction to the caller’s return variable. See also Decoder.last_error.

Returns:

The next instruction

Return type:

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 = 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.decode is 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:

ConstantOffsets

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 current IP/EIP/RIP value, see also Decoder.position

Note

The setter only updates the IP value, it does not change the data position, use the Decoder.position setter to change the position.

Type:

int

last_error

Gets the last decoder error (a DecoderError enum value).

Unless you need to know the reason it failed, it’s better to check Instruction.is_invalid or if not instruction:.

Type:

DecoderError

max_position

(usize) Gets the max value that can be written to Decoder.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:

int

position

(usize) The current data position, which is the index into the data passed to the constructor.

This value is always <= Decoder.max_position. When Decoder.position == Decoder.max_position, it’s not possible to decode more instructions and Decoder.can_decode returns False.

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:

int