Consider the following instruction:
8D 8C 4E B0 2F FF FF LEA ECX, [ESI+ECX*2-0xD050]
Using IDAPython, how can I extract the structure of the second operand? I'd like to know things like:
ESI
is the base registerECX
is the index register2
is the index constant-0xD050
is the displacement constant
Its ok if I have to make a bunch of IDAPython API calls together. So far, I've had to resort to string parsing, and I'd really like to get rid of this.
The most relevant API function I've found is idautils.DecodeInstruction()
, yet it doesn't seem to completely cover the structure of the second operand. See below for my exploration:
i = idautils.DecodeInstruction(<ea from above>)
# operand type
assert i.Op2.type == idc.o_disp
# operand value type
assert i.Op2.dtyp == idc.dt_dword
# operand flags
assert i.Op2.flags == idc.OF_SHOW
# structure of o_displ operand is like:
#
# Memory Reg [Base Reg + Index Reg + Displacement].
def get_reg_const(reg):
'''
fetch register number from string name.
'''
ri = idaapi.reg_info_t()
idaapi.parse_reg_name(reg, ri)
return ri.reg
# we probably expect to find these constants in the operand structure
assert get_reg_const('ecx') == 1
assert get_reg_const('esi') == 6
# the operand structure
assert unsigned2signed(i.Op2.addr) == 0xD050 # displacement
assert i.Op2.n == 1 # operand number
assert i.Op2.phrase == 4 # "number of register phrase", don't know what this means
assert i.Op2.reg == 4 # "number of register", don't see how this applies
assert i.Op2.specflag1 == 1 # unknown interpretation, could be "ecx"!?!
assert i.Op2.specflag2 == 78 # 0x4E, unknown interpretation
assert i.Op2.specflag3 == 0 # probably empty
assert i.Op2.specflag4 == 0 # probably empty
assert i.Op2.specval == 0x200000 # unknown interpretation
assert i.Op2.value == 0 # "outer displacement" (none here)
get_op_tinfo2
,get_operand_immvals
,get_opinfo