def __call__(self):
     if self.op == 'hex':
         ida_bytes.op_hex(self.ea, self.n)
     if self.op == 'bin':
         ida_bytes.op_bin(self.ea, self.n)
     if self.op == 'dec':
         ida_bytes.op_dec(self.ea, self.n)
     if self.op == 'chr':
         ida_bytes.op_chr(self.ea, self.n)
     if self.op == 'oct':
         ida_bytes.op_oct(self.ea, self.n)
     if self.op == 'enum':
         id = ida_enum.get_enum(Event.encode(self.extra['ename']))
         ida_bytes.op_enum(self.ea, self.n, id, self.extra['serial'])
     if self.op == 'struct':
         path_len = len(self.extra['spath'])
         path = ida_pro.tid_array(path_len)
         for i in xrange(path_len):
             sname = Event.encode(self.extra['spath'][i])
             path[i] = ida_struct.get_struc_id(sname)
         insn = ida_ua.insn_t()
         ida_ua.decode_insn(insn, self.ea)
         ida_bytes.op_stroff(insn, self.n, path.cast(), path_len,
                             self.extra['delta'])
     if self.op == 'stkvar':
         ida_bytes.op_stkvar(self.ea, self.n)
 def calls_to(self) -> Iterable[int]:
     """Iterates addresses that call this function."""
     for ea in self.xrefs_to:
         insn = ida_ua.insn_t()
         ida_ua.decode_insn(insn, ea)
         if ida_idp.is_call_insn(insn):
             yield ea
示例#3
0
    def get_operands(self, ip=None):
        """
        Gets the Operand objects of all operands in the current instruction and returns them in a list.

        :param int ip: location of instruction pointer to pull operands from (defaults to current rip in context)

        :return: list of Operand objects
        """
        if ip is None:
            ip = self.ip

        operands = []
        cmd = ida_ua.insn_t()
        # NOTE: We can't trust the instruction length returned by decode_ins.
        ida_ua.decode_insn(cmd, ip)
        for idx, op in enumerate(cmd.ops):
            operand = Operand(self, ip, idx)
            # IDA will sometimes create hidden or "fake" operands.
            # These are there to represent things like an implicit EAX register.
            # To help avoid confusion to the opcode developer, these fake operands will not be included.
            if not operand.is_hidden:
                operands.append(operand)

            if operand.is_void:
                break  # no more operands

        return operands
示例#4
0
    def get_operands(self, ip=None) -> List[Operand]:
        """
        Gets the Operand objects of all operands in the current instruction and returns them in a list.

        :param int ip: location of instruction pointer to pull operands from (defaults to current rip in context)

        :return: list of Operand objects
        """
        if ip is None:
            ip = self.ip

        # Calling insn_t() and decode_insn() is somewhat expensive and this function gets called a LOT,
        # so we are going to cache the operand indices.
        try:
            indices = self._operand_indices[ip]
        except KeyError:
            indices = []
            insn = ida_ua.insn_t()
            # NOTE: We can't trust the instruction length returned by decode_ins.
            ida_ua.decode_insn(insn, ip)
            for idx, op in enumerate(insn.ops):
                if op.type == ida_ua.o_void:
                    break  # no more operands

                # IDA will sometimes create hidden or "fake" operands.
                # These are there to represent things like an implicit EAX register.
                # To help avoid confusion to the opcode developer, these fake operands will not be included.
                # TODO: Checking shown() may not work as expected.
                #   If things explode, go back to checking operand.is_hidden
                if op.shown():
                    indices.append((idx, op.type))

            self._operand_indices[ip] = indices

        return [Operand(self, ip, idx, _type=type) for idx, type in indices]
示例#5
0
 def __call__(self):
     if self.op == "hex":
         ida_bytes.op_hex(self.ea, self.n)
     if self.op == "bin":
         ida_bytes.op_bin(self.ea, self.n)
     if self.op == "dec":
         ida_bytes.op_dec(self.ea, self.n)
     if self.op == "chr":
         ida_bytes.op_chr(self.ea, self.n)
     if self.op == "oct":
         ida_bytes.op_oct(self.ea, self.n)
     if self.op == "offset":
         ida_idc.op_plain_offset(self.ea, self.n, 0)
     if self.op == "enum":
         id = ida_enum.get_enum(self.extra["ename"])
         ida_bytes.op_enum(self.ea, self.n, id, self.extra["serial"])
     if self.op == "struct":
         path_len = len(self.extra["spath"])
         path = ida_pro.tid_array(path_len)
         for i in range(path_len):
             sname = self.extra["spath"][i]
             path[i] = ida_struct.get_struc_id(sname)
         insn = ida_ua.insn_t()
         ida_ua.decode_insn(insn, self.ea)
         ida_bytes.op_stroff(insn, self.n, path.cast(), path_len,
                             self.extra["delta"])
     if self.op == "stkvar":
         ida_bytes.op_stkvar(self.ea, self.n)
示例#6
0
 def _on_optypechanged(self, ea, n, op, extra):
     if op == 'hex':
         ida_bytes.op_hex(ea, n)
     if op == 'bin':
         ida_bytes.op_bin(ea, n)
     if op == 'dec':
         ida_bytes.op_dec(ea, n)
     if op == 'chr':
         ida_bytes.op_chr(ea, n)
     if op == 'oct':
         ida_bytes.op_oct(ea, n)
     if op == 'stkvar':
         ida_bytes.op_stkvar(ea, n)
     if op == 'enum':
         enum_id = ida_enum.get_enum(str(extra['ename']))
         ida_bytes.op_enum(ea, n, enum_id, extra['serial'])
     if op == 'struct':
         path_length = len(extra['spath'])
         path = ida_pro.tid_array(path_length)
         for i in range(path_length):
             sname = str(extra['spath'][i])
             path[i] = ida_struct.get_struc_id(sname)
         insn = ida_ua.insn_t()
         ida_ua.decode_insn(insn, ea)
         ida_bytes.op_stroff(insn, n, path.cast(), path_length,
                             extra['delta'])
def determine_api_number(ea, chunk_start, chunk_end):
    def get_reg_num(reg_name):
        reg_inf = ida_idp.reg_info_t()
        ida_idp.parse_reg_name(reg_inf, reg_name)
        return reg_inf.reg

    insn = ida_ua.insn_t()
    ida_ua.decode_insn(insn, ea)
    if insn.itype != ida_allins.ARM_ldr \
            or insn.ops[0].type != ida_ua.o_reg:
        reg = -1
    else:
        reg = insn.ops[0].reg

    reg_val = -1
    ins_ea = chunk_start
    while ins_ea < chunk_end:
        insn = ida_ua.insn_t()
        ins_len = max(1, ida_ua.decode_insn(insn, ins_ea))

        if insn.itype == ida_allins.ARM_mov \
                and insn.ops[0].type == ida_ua.o_reg \
                and insn.ops[0].reg == get_reg_num('R0') \
                and insn.ops[1].type == ida_ua.o_imm:
            reg_val = insn.ops[1].value

        if insn.itype == ida_allins.ARM_bx \
                and insn.ops[0].type == ida_ua.o_reg \
                and (insn.ops[0].reg == reg or reg == -1):
            break
        ins_ea += ins_len
    return reg_val
示例#8
0
def op_stroff(*args):
    insn, n, path, path_len, delta = args
    import ida_ua
    if not isinstance(insn, ida_ua.insn_t):
        tmp = ida_ua.insn_t()
        ida_ua.decode_insn(tmp, insn)
        insn = tmp
    return _ida_bytes.op_stroff(insn, n, path, path_len, delta)
 def _insn(self):
     if not self.__insn:
         insn = ida_ua.insn_t()
         ida_ua.decode_insn(insn, self.ip)
         if not insn:
             raise FunctionTracingError(f"Failed to decode instruction at 0x{self.ip:X}")
         self.__insn = insn
     return self.__insn
示例#10
0
 def _insn(self):
     if self.__insn:
         return self.__insn
     insn = ida_ua.insn_t()
     ida_ua.decode_insn(insn, self.ip)
     if not insn:
         raise FunctionTracingError("Failed to decode instruction at 0x:{:X}".format(self.ip))
     self.__insn = insn
     return self.__insn
 def calls_from(self) -> Iterable[Tuple[int, int]]:
     """Iterates call address and callee address of the calls within this function."""
     for ea in self.heads():
         insn = ida_ua.insn_t()
         ida_ua.decode_insn(insn, ea)
         if ida_idp.is_call_insn(insn):
             for xref in idautils.XrefsFrom(ea, idaapi.XREF_FAR):
                 func_ea = xref.to
                 if func_ea:
                     yield ea, func_ea
示例#12
0
    def FillOutBlock(self):
        end_insn = ida_ua.insn_t()
        ida_ua.decode_insn(end_insn, self.end_ea)

        curr_insn_ea = self.start_ea
        while curr_insn_ea != self.end_ea + end_insn.size:
            #
            #   Walk and add each address to the list of instruction addresses
            #
            curr_insn = ida_ua.insn_t()
            ida_ua.decode_insn(curr_insn, curr_insn_ea)
            self.instruction_addresses.append(curr_insn_ea)
            curr_insn_ea = curr_insn_ea + curr_insn.size
示例#13
0
    def _insn(self):
        """
            Property which return an ``insn_t`` representing the instruction
            as provided by IDA.
            
            There is no reason to use this except for interfacing directly
            with IDA functions.

            This is use internally by other functions.
        """
        i = ida_ua.insn_t()
        ida_ua.decode_insn(
            i, self.ea)  # decode and not create for not changing the db
        return i
示例#14
0
def decode_instruction(ea):
  """Read the bytes of an x86/amd64 instruction. This handles things like
  combining the bytes of an instruction with its prefix. IDA Pro sometimes
  treats these as separate."""
  global _NOT_INST_EAS, _BAD_INSTRUCTION, PREFIX_ITYPES

  if ea in _NOT_INST_EAS:
    return _BAD_INSTRUCTION

  decoded_inst = ida_ua.insn_t()
  inslen = ida_ua.decode_insn(decoded_inst, ea)
  if inslen <= 0:
    _NOT_INST_EAS.add(ea)
    return _BAD_INSTRUCTION

  assert decoded_inst.ea == ea
  end_ea = ea + decoded_inst.size

  decoded_bytes = read_bytes_slowly(ea, end_ea)

  # We've got an instruction with a prefix, but the prefix is treated as
  # independent.
  if 1 == decoded_inst.size and decoded_inst.itype in PREFIX_ITYPES:
    decoded_inst, extra_bytes = decode_instruction(end_ea)
    decoded_bytes += extra_bytes

  return decoded_inst, decoded_bytes
def get_dispatcher(handler):
    """Retrieves the dispatcher of the TL/DR API calls

    :param handler: Handler of the TL/DR API calls
    :type handler: int
    :return: Dispatcher for the TL/DR API calls
    :rtype: int
    """

    func = ida_funcs.get_func(handler)
    insn = ida_ua.insn_t()
    ea = 0
    branch_addr = -1

    ea = func.start_ea

    while ea < func.end_ea:
        insn = ida_ua.insn_t()
        insn_len = max(1, ida_ua.decode_insn(insn, ea))
        if insn.itype == ida_allins.ARM_bl and \
                insn.ops[0].type == ida_ua.o_near:
            branch_addr = insn.ops[0].addr
            break
        ea += insn_len

    return branch_addr
        def analyze_block(block):
            """Analyze a basic bloc and return its successors, if it's correspond to a basic bloc treating the Driver case and the address for the DR/TL API table if one is loaded

            :param block: Basic block to analyze
            :type block: ida_gdl.BasicBlock
            :return: Successors Basic Blocks, if it deals with Secure Driver case, and the address of the table loaded if loaded
            :rtype: (Generator, bool, int)
            """

            loaded_value = -1
            is_dr_table = False
            insn = ida_ua.insn_t()
            insn_ea = block.start_ea
            insn_len = 0

            while insn_ea < block.end_ea:
                insn_len = max(1, ida_ua.decode_insn(insn, insn_ea))
                if insn.itype == ida_allins.ARM_sub and \
                        insn.ops[2].type == ida_ua.o_imm and \
                        insn.ops[2].value == 0x1000:
                    is_dr_table = True
                if insn.itype == ida_allins.ARM_ldr and \
                        insn.ops[1].type == ida_ua.o_mem:
                    pool_value = ida_bytes.get_dword(insn.ops[1].addr)
                    value = ida_bytes.get_dword(pool_value)
                    if value > 0x1000:
                        loaded_value = pool_value
                insn_ea += insn_len
            return block.succs(), is_dr_table, loaded_value
    def get_cmp(func_start, func_end):
        """Retrives the address of the CMP within the dispatching function

        :param func_start: Beginning of the dispatching function
        :type func_start: int
        :param func_end: Ending of the dispatching function
        :type func_end: int
        :return: Address of the CMP within the dispatching function
        :rtype: int
        """

        cmp_addr = -1
        insn_ea = func_start
        insn = ida_ua.insn_t()
        insn_len = 0

        while insn_ea < func_end:
            insn_len = max(1, ida_ua.decode_insn(insn, insn_ea))
            if insn.itype == ida_allins.ARM_cmp and \
                    insn.ops[1].type == ida_ua.o_imm and \
                    insn.ops[1].value == 0x1000:
                cmp_addr = insn_ea
                break
            insn_ea += insn_len
        return cmp_addr
示例#18
0
 def activate(self, ctx):
     cur_ea = ida_kernwin.get_screen_ea()
     pfn = ida_funcs.get_func(cur_ea)
     if pfn:
         v = ida_kernwin.get_current_viewer()
         result = ida_kernwin.get_highlight(v)
         if result:
             stkvar_name, _ = result
             frame = ida_frame.get_frame(cur_ea)
             sptr = ida_struct.get_struc(frame.id)
             mptr = ida_struct.get_member_by_name(sptr, stkvar_name)
             if mptr:
                 fii = ida_funcs.func_item_iterator_t()
                 ok = fii.set(pfn)
                 while ok:
                     ea = fii.current()
                     F = ida_bytes.get_flags(ea)
                     for n in range(ida_ida.UA_MAXOP):
                         if not ida_bytes.is_stkvar(F, n):
                             continue
                         insn = ida_ua.insn_t()
                         if not ida_ua.decode_insn(insn, ea):
                             continue
                         v = ida_frame.calc_stkvar_struc_offset(
                             pfn, insn, n)
                         if v >= mptr.soff and v < mptr.eoff:
                             print("Found xref at 0x%08x, operand #%d" %
                                   (ea, n))
                     ok = fii.next_code()
             else:
                 print("No stack variable named \"%s\"" % stkvar_name)
     else:
         print("Please position the cursor within a function")
示例#19
0
def get_instruction(address: int) -> ida_ua.insn_t:
    """
    Obtains insn_t object for instruction.
    """
    insn_t = ida_ua.insn_t()
    if ida_ua.decode_insn(insn_t, address):
        return insn_t
示例#20
0
def decode_instruction(ea):
    """Read the bytes of an x86/amd64 instruction. This handles things like
  combining the bytes of an instruction with its prefix. IDA Pro sometimes
  treats these as separate."""
    global _NOT_INST_EAS, _BAD_INSTRUCTION, PREFIX_ITYPES

    if ea in _NOT_INST_EAS:
        return _BAD_INSTRUCTION

    decoded_inst = ida_ua.insn_t()
    inslen = ida_ua.decode_insn(decoded_inst, ea)
    if inslen <= 0:
        _NOT_INST_EAS.add(ea)
        return _BAD_INSTRUCTION

    assert decoded_inst.ea == ea
    end_ea = ea + decoded_inst.size

    decoded_bytes = read_bytes_slowly(ea, end_ea)

    # We've got an instruction with a prefix, but the prefix is treated as
    # independent.
    if 1 == decoded_inst.size and decoded_inst.itype in PREFIX_ITYPES:
        decoded_inst, extra_bytes = decode_instruction(end_ea)
        decoded_bytes += extra_bytes

    return decoded_inst, decoded_bytes
示例#21
0
 def _is_ret(self, x):
     if can_decode(x):
         insn = insn_t()
         inslen = decode_insn(insn, x)
         if inslen > 0 and is_ret_insn(insn):
             return True
     return False
def get_handler(mclib_jumper):
    """Retrieves the handler of the TL/DR API calls

    :param mclib_jumper: Address of the McLib jumper
    :type mclib_jumper: int
    :return: Handler of the TL/DR API calls
    :rtype: int
    """
    handler = -1
    insn = ida_ua.insn_t()

    ida_ua.decode_insn(insn, mclib_jumper)
    if insn.itype == ida_allins.ARM_adr and \
            insn.ops[0].type == ida_ua.o_reg and \
            insn.ops[0].reg == get_reg_num("PC") and \
            insn.ops[1].type == ida_ua.o_imm:
        handler = insn.ops[1].value
    return handler
def doit(cur_ea):
    global stk

    #decode
    insn = ida_ua.insn_t()
    lenn = ida_ua.decode_insn(insn, cur_ea)
    #execute
    execute(insn)
    return ida_search.find_code(cur_ea, SEARCH_DOWN)
示例#24
0
def processRefs(output):
    """
    process all the xrefs that ida recognizes

    params:
        output: protobuf file path
    returns:
    """

    refInf = refInf_pb2.RefList()
    # iterate over all valid terms
    for head in idautils.Heads():
        is_code = False
        candidateRefs = None
        if idc.is_code(idc.get_full_flags(head)):
            is_code = True
            decoded_inst = ida_ua.insn_t()
            insn_len = ida_ua.decode_insn(decoded_inst, head)
            if insn_len > 0:
                candidateRefs = getCandidateRefsFromInsn(decoded_inst)
        if is_code and candidateRefs == None:
            continue

        for xref in idautils.XrefsFrom(head, 0):
            ref_from = head
            target_addr = xref.to
            # check if target_addr is in current instruction internal representation
            if is_code:
                if target_addr not in candidateRefs:
                    continue
                else:
                    ref_from = candidateRefs[target_addr]
            if is_invalid_ea(target_addr):
                continue

            logging.debug(
                "Ref: 0x%x -> 0x%x, type is %s" %
                (ref_from, target_addr, idautils.XrefTypeName(xref.type)))
            ref = refInf.ref.add()
            ref.ref_va = ref_from
            ref.target_va = target_addr
            # default value
            ref.ref_size = 8
            target_is_code = idc.is_code(idc.get_full_flags(target_addr))
            if is_code and target_is_code:
                ref.kind = 0  # c2c
            elif is_code and not target_is_code:
                ref.kind = 1  # c2d
            elif not is_code and target_is_code:
                ref.kind = 2  # d2c
            else:
                ref.kind = 3  # d2d

    ## save the protobuf result
    with open(output, 'wb') as pbOut:
        pbOut.write(refInf.SerializeToString())
示例#25
0
def DecodeInstruction(ea):
    """
    Decodes an instruction and returns an insn_t like class

    @param ea: address to decode
    @return: None or a new insn_t instance
    """
    insn = ida_ua.insn_t()
    inslen = ida_ua.decode_insn(insn, ea)
    return insn if inslen > 0 else None
示例#26
0
def DecodeInstruction(ea):
    """
    Decodes an instruction and returns an insn_t like class

    @param ea: address to decode
    @return: None or a new insn_t instance
    """
    inslen = ida_ua.decode_insn(ea)
    if inslen == 0:
        return None

    return ida_ua.cmd.copy()
示例#27
0
文件: hierarchy.py 项目: clayne/abyss
def Callees(ea):
    pfn = ida_funcs.get_func(ea)
    callees = []
    if pfn:
        for item in pfn:
            F = ida_bytes.get_flags(item)
            if ida_bytes.is_code(F):
                insn = ida_ua.insn_t()
                if ida_ua.decode_insn(insn, item):
                    if ida_idp.is_call_insn(insn):
                        if insn.ops[0].type in [ida_ua.o_near, ida_ua.o_far]:
                            callees.append(insn.ops[0].addr)
    return list(dict.fromkeys(callees))
示例#28
0
文件: amie.py 项目: pharazone/AMIE
    def hint(self, ea, tag, val):
        val = val.strip()
        if not val:
            return None

        if tag == ida_lines.SCOLOR_REG:
            if val in self.regs:
                register = self.regs[val]
                return register["long_name"], register["purpose"]

        elif tag == ida_lines.SCOLOR_INSN:
            insn = ida_ua.insn_t()
            ida_ua.decode_insn(insn, ea)
            insn_bs = ida_bytes.get_bytes(insn.ea, insn.size)
            fmt = {2: "<H", 4: "<I", 8: "<Q"}
            insn_bs = struct.unpack(fmt.get(len(insn_bs)), insn_bs)[0]

            enc_type = "A64"
            if isinstance(self, AArch32):
                enc_type = "A32"
                if ida_segregs.get_sreg(ea, 20) > 0:
                    enc_type = "T32"

            insn_enc = self.find_insn_enc(
                enc_type, insn_bs, insn.get_canon_mnem()
            )
            if not insn_enc:
                return
            insn_name, tmpl_name = insn_enc
            insn = self.insns[insn_name]

            desc = insn["authored"]
            if tmpl_name in insn["templates"]:
                desc += "\n\n" + "\n".join(insn["templates"][tmpl_name])
            return insn["heading"], desc

        elif tag == ida_lines.SCOLOR_KEYWORD:
            if val in self.data["keywords"]:
                return val, self.data["keywords"][val]
示例#29
0
    def __init__(self, insn_ea):
        """

        :param insn_ea:
        """
        if not ida_ua.can_decode(insn_ea):
            raise InstructionException("Cannot decode instruction @ %07X" %
                                       insn_ea)

        self.size = ida_ua.decode_insn(insn_ea)
        self.insn = idaapi.cmd
        self.ops = self.insn.ops
        self.itype = self.insn.itype
        self.ea = self.insn.ea
示例#30
0
    def CheckZFEmulatedCall(self, EffectiveAddress):
        '''
            @brief  Identify emulated function calls.

            @detail 

            push    <return address>
	        0000    JZ      xxxxxxxx
	        0001    JNZ     0010


            @returns The return address that is pushed to the stack for the CALL instruction
        '''

        rtrn_addr = idc.BADADDR

        push_instr_ea = EffectiveAddress

        push_insn = ida_ua.insn_t()
        ida_ua.decode_insn(push_insn, push_instr_ea)

        if maze_deobf_utils.CheckValidTargettingInstr(push_insn, "push"):
            """
                Valid PUSH instruction.
            """

            jz_insn_ea = push_instr_ea + push_insn.size()
            jz_insn = ida_ua.insn_t()
            ida_ua.decode_insn(jz_insn, jz_insn_ea)

            if maze_deobf_utils.CheckValidTargettingInstr(push_insn, "push"):
                """
                    Valid PUSH instruction.
                """

        return rtrn_addr
示例#31
0
                def visit_expr(self, e):
                    if not e.x or e.x.op != ida_hexrays.cot_helper:
                        return 0

                    insn = ida_ua.insn_t()
                    ida_ua.decode_insn(insn, e.ea)

                    def make_reg(cp_reg):
                        reg = ida_hexrays.carg_t()
                        reg.op = ida_hexrays.cot_helper
                        reg.helper = cp_reg
                        reg.exflags = ida_hexrays.EXFL_ALONE
                        return reg

                    if e.x.helper in ["__mcr", "__mrc"]:
                        cp_reg = plugin.arch.decode_mcr_mrc(insn)[0]
                        if cp_reg:
                            if e.x.helper == "__mcr":
                                e.x.helper = "_WriteStatusReg"
                                val = ida_hexrays.carg_t()
                                e.a[2].swap(val)
                                e.a.clear()
                                e.a.push_back(make_reg(cp_reg))
                                e.a.push_back(val)

                            else:
                                e.x.helper = "_ReadStatusReg"
                                e.a.clear()
                                e.a.push_back(make_reg(cp_reg))

                    elif e.x.helper == "ARM64_SYSREG":
                        cp_reg = plugin.arch.decode_msr_mrs(insn)[0]
                        if cp_reg:
                            e.replace_by(make_reg(cp_reg))

                    return 0
示例#32
0
def IsPrevInsnCall(ea):
    """
    Given a return address, this function tries to check if previous instruction
    is a CALL instruction
    """
    global CallPattern
    if ea == ida_idaapi.BADADDR or ea < 10:
        return None

    for delta, opcodes in CallPattern:
        # assume caller's ea
        caller = ea + delta
        # get the bytes
        bytes = [x for x in idautils.GetDataList(caller, len(opcodes), 1)]
        # do we have a match? is it a call instruction?
        if bytes == opcodes:
            insn = ida_ua.insn_t()
            if ida_ua.decode_insn(insn, caller) and ida_idp.is_call_insn(insn):
                return caller
    return None
示例#33
0
文件: insn_trace.py 项目: Rupan/ida
 def dbg_trace(self, tid, ip):
     if ip in self._visited_addrs:
         return 1
     self._visited_addrs.add(ip)
     if idc.is_unknown(ida_bytes.get_flags(ip)):
         ida_ua.create_insn(ip)
     else:
         idc.msg(
             'Skipping explored EA at address 0x{0:X}\n'.format(ip)
         )
     # print idc.generate_disasm_line(ip, 0)
     if ida_ua.decode_insn(ip) > 0:
         if 'ret' in ida_ua.cmd.get_canon_mnem().lower():
             idc.msg('Found ret instruction, suspending execution\n')
             ida_dbg.suspend_process()
     else:
         idc.msg(
             'Unable to decode instruction at address 0x{0:X}\n'.format(ip)
         )
         ida_dbg.suspend_process()
     return 0