考虑以下指令:
8D 8C 4E B0 2F FF FF LEA ECX, [ESI+ECX*2-0xD050]
使用 IDAPython,如何提取第二个操作数的结构?我想知道这样的事情:
ESI是基址寄存器ECX是索引寄存器2是指数常数-0xD050是位移常数
如果我必须一起进行一堆 IDAPython API 调用,那也没关系。到目前为止,我不得不求助于字符串解析,我真的很想摆脱它。
我发现的最相关的 API 函数是idautils.DecodeInstruction(),但它似乎并没有完全覆盖第二个操作数的结构。我的探索见下文:
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)