def memory(ea, op):
'''Operand type decoder for memory-type operands which return an address.'''
if op.type in {idaapi.o_mem, idaapi.o_far, idaapi.o_near, idaapi.o_displ}:
seg, sel = (op.specval & 0xffff0000) >> 16, (op.specval & 0x0000ffff) >> 0
return op.addr
optype = map(utils.funbox("{:s}({:d})".format), [('idaapi.o_far', idaapi.o_far), ('idaapi.o_near', idaapi.o_near)])
raise E.InvalidTypeOrValueError(u"{:s}.address({:#x}, {!r}) : Expected operand type `{:s}` or `{:s}` but operand type {:d} was received.".format('.'.join((__name__, 'operand_types')), ea, op, optype[0], optype[1], op.type))
def get_opcodes(addr, strict):
"""Get current bytes of the instruction pointed at addr.
Args:
addr: address of the current instruction
strict: be more restrictive when applying wildcards (True) or not (False)
Returns:
String: hex-encoded representation of the bytes obtained at addr
"""
if strict:
offsets_types = {idaapi.o_far, idaapi.o_mem, idaapi.o_imm}
else:
offsets_types = {idaapi.o_far, idaapi.o_mem}
pattern = ''
mnem = idautils.DecodeInstruction(addr)
if mnem is not None:
op1_type = mnem.Op1.type
op2_type = mnem.Op2.type
logging.debug(
'[VTGREP] Instruction: %s [%d, %d, %d]',
idc.generate_disasm_line(addr, 0),
mnem.itype,
op1_type,
op2_type
)
inst_len = idc.get_item_size(addr)
drefs = [x for x in idautils.DataRefsFrom(addr)]
# Checks if any operand constains a memory address
if (drefs and
((op1_type == idaapi.o_imm) or (op2_type == idaapi.o_imm)) or
op1_type in offsets_types or op2_type in offsets_types):
pattern = Disassembler.wildcard_instruction(addr)
# Checks if the instruction is a CALL (near or far) or
# if it's a JMP (excluding near jumps)
else:
if ((mnem.itype == idaapi.NN_call) or
(mnem.itype == idaapi.NN_jmp and op1_type != idaapi.o_near)):
pattern = Disassembler.wildcard_instruction(addr)
# In any other case, concatenate the raw bytes to the current string
else:
pattern = binascii.hexlify(idc.get_bytes(addr, inst_len))
pattern = pattern.decode('utf-8')
return pattern
else: return 0