示例#1
0
def is_stc_jb(ea):
    """
    like:

        .text:00401042                 stc
        .text:00401043                 jb      short loc_401046
        .text:00401043 ; ---------------------------------------------------------------------------
        .text:00401045                 db 0B1h ; ±
        .text:00401046 ; ---------------------------------------------------------------------------
        .text:00401046
        .text:00401046 loc_401046:                             ; CODE XREF: .text:00401043↑j
        .text:00401046                 mov     eax, 0
    """
    insn = idautils.DecodeInstruction(ea)
    if insn is None:
        return False, None

    if insn.get_canon_mnem() != "stc":
        return False, None

    next_ea = insn.ea + insn.size

    insn = idautils.DecodeInstruction(next_ea)
    if insn is None:
        return False, None

    if insn.get_canon_mnem() != "jb":
        return False, None

    if insn.ops[0].addr != insn.ea + insn.size + 1:
        return False, None

    return True, 4
示例#2
0
def is_clc_jnb(ea):
    """
    like:

        .text:0040139E                 clc
        .text:0040139F                 jnb     short loc_4013A2
        .text:0040139F ; ---------------------------------------------------------------------------
        .text:004013A1                 db  0Fh
        .text:004013A2 ; ---------------------------------------------------------------------------
        .text:004013A2
        .text:004013A2 loc_4013A2:                             ; CODE XREF: .text:0040139F↑j
        .text:004013A2                 mov     eax, 0x0
    """
    insn = idautils.DecodeInstruction(ea)
    if insn is None:
        return False, None

    if insn.get_canon_mnem() != "clc":
        return False, None

    next_ea = insn.ea + insn.size

    insn = idautils.DecodeInstruction(next_ea)
    if insn is None:
        return False, None

    if insn.get_canon_mnem() != "jnb":
        return False, None

    if insn.ops[0].addr != insn.ea + insn.size + 1:
        return False, None

    return True, 4
示例#3
0
def is_locate_protocol_param(xref):
    """
    Returns True if the xref is the 'Protocol' parameter of this function :
    typedef EFI_STATUS LocateProtocol (
        IN  EFI_GUID *Protocol,
        IN  VOID     *Registration OPTIONAL,
        OUT VOID     **Interface
    );
    """
    inst = idautils.DecodeInstruction(xref)

    if inst is None:
        return False

    # Must be 'lea rcx, gSmtGuid'
    if inst.get_canon_mnem() != 'lea' or inst.Op1.type != ida_ua.o_reg or \
       inst.Op1.reg != ida_idp.str2reg('rcx'):
        return False

    # Look up to 5 instructions ahead to find:
    # call    [rax+EFI_BOOT_SERVICES.LocateProtocol]
    for addr in get_func_items_from_xref(xref)[:5]:
        inst = idautils.DecodeInstruction(addr)
        if inst.get_canon_mnem() == 'call':
            if inst.Op1.type == ida_ua.o_displ and \
               get_operand_struct_name(inst, 0) == 'EFI_BOOT_SERVICES' and \
               inst.Op1.addr == 0x140:
                return True
            else:
                # Bail out if we hit a call that is not LocateProtocol
                break

    return False
示例#4
0
def decode(ea=None):
    if ea == None:
        ea = idc.ScreenEA()
    ist = idautils.DecodeInstruction(ea)
    if ist == None:
        return None

    _bytes = map(lambda x: chr(idc.Byte(ea + x)), range(ist.size))
    _bytes = ''.join(_bytes)

    ist = distorm3.Decompose(ea, _bytes)[0]

    # distorm doesn't decode the operand logical size ie.. byte ptr, so use IDA for that
    for i in range(len(ist.operands)):
        idaop = idautils.DecodeInstruction(ist.address)[i]
        setattr(ist.operands[i], 'op_size', op_size(idaop))

    def _get_operand_sym(op):
        if op.type == 'Immediate':
            return symath.symbolic(op.value)
        elif op.type == 'AbsoluteMemoryAddress':
            return DEREF(op.op_size, op.disp)
        elif op.type == 'Register':
            return symath.symbols(distorm3.Registers[op.index].upper())
        elif op.type == 'AbsoluteMemory':
            rv = 0

            if op.index != None:
                rv += symath.symbols(
                    distorm3.Registers[op.index].upper()) * op.scale
            if op.base != None:
                rv += symath.symbols(distorm3.Registers[op.base].upper())
            if op.disp != None:
                rv += symath.symbolic(op.disp)

            return DEREF(op.op_size, rv)
        else:
            raise BaseException("Unknown operand type %s (%s)" % (op.type, op))

    args = list(map(_get_operand_sym, ist.operands))

    if ist.mnemonic.lower() == 'call':
        spdiff = idc.GetSpDiff(ist.address + ist.size)
        if spdiff == None:
            spdiff = 0
        try:
            return Call(args[0], spdiff, ist.address)
        except Exception as ex:
            print 'failed to wrap call @%x' % (ist.address)
            raise ex
    else:
        return symath.symbolic(ist.mnemonic.lower())(*args)
示例#5
0
def create_vtable_struct(start_address, vtable_name, p_vtable_addr, offset):
    struct_name = vtable_name + "_struct"
    struct_id = add_struc(-1, struct_name, 0)
    if struct_id != idc.BADADDR:
        add_all_functions_to_struct(start_address, struct_id, p_vtable_addr, offset)
        idc.op_stroff(idautils.DecodeInstruction(get_pc_value()), 1, struct_id, 0)
    else:
        struct_id = ida_struct.get_struc_id(struct_name)
        # Checks if the struct exists, in this case the function offset will be added to the struct
        if struct_id != idc.BADADDR:
            idc.op_stroff(idautils.DecodeInstruction(get_pc_value()), 1, struct_id, 0)
        else:
            print ("Failed to create struct: " +  struct_name)
def fix_block_link(switch_info, block_info):
    block_end = block_info.end
    dispatcher = block_info.dispatcher

    head = block_info.start
    br_dispatcher_insn = None
    while head < block_end + 2:
        inst = idautils.DecodeInstruction(head)
        head += 2
        if inst is None:
            continue
        # 00019C82                 PUSH            {R0,R1,LR}
        # 00019C84                 LDR             R0, =0x16A
        # 00019C86                 LDR             R1, loc_19C88
        # 00019C88
        # 00019C88 loc_19C88                               ; CODE XREF: LOAD:0001A262↓j
        # 00019C88                                         ; LOAD:0001A97A↓j ...
        # 00019C88                 BL              sub_2A584

        print('entry block {:08x} {:08x}'.format(inst.ea, dispatcher))
        if inst.ea == dispatcher:
            br_dispatcher_insn = inst.ea - 2
            break

        if inst.itype == idaapi.ARM_bl and inst.Op1.type == o_near and inst.Op1.addr == dispatcher:
            br_dispatcher_insn = inst.ea
            break

    if br_dispatcher_insn:
        push_insn = find_push(br_dispatcher_insn)
        patch_pos = push_insn.ea
        assert push_insn
        addr = skip_nop(push_insn.ea + push_insn.size)
        print('skip_nop {:08x}'.format(push_insn.ea))
        ldr_insn = idautils.DecodeInstruction(addr)
        idx = get_ldr_value(ldr_insn)
        next_block_info = switch_info[idx]
        asm = 'b.w #%s' % (rel(next_block_info.start - 4, patch_pos))
        codes, _ = ks.asm(asm, patch_pos)
        fill_ops(patch_pos, codes)

        fill_beg = patch_pos + len(codes)
        fill_end = block_info.end
        fill_nop(fill_beg, fill_end - fill_beg)

        print('link BB: %s ==> %s' % (block_info, switch_info[idx]))
    else:
        print('successor not found BB: %s' % block_info)
示例#7
0
    def _get_constant_ref(self, opnum=0):
        '''
        Return the constant value, if any, reference by the instruction.

        @author: Peter Silberman

        @rtype:  Mixed
        @return: Integer value of referenced constant, otherwise None.
        '''

        if idaapi.IDA_SDK_VERSION >= 600:
            instruction = idaapi.cmd.ea
        else:
            instruction = idaapi.get_current_instruction()

        if not instruction:
            return None

        if opnum:
            if idaapi.IDA_SDK_VERSION >= 600:
                op0 = idautils.DecodeInstruction(instruction)[opnum]
            else:
                op0 = idaapi.get_instruction_operand(instruction, opnum)

            if op0.value and op0.type == o_imm and GetStringType(
                    self.ea) == None:
                return op0.value

        else:
            if idaapi.IDA_SDK_VERSION >= 600:
                op0 = idautils.DecodeInstruction(instruction)[0]
            else:
                op0 = idaapi.get_instruction_operand(instruction, 0)

            if op0.value and op0.type == o_imm and GetStringType(
                    self.ea) == None:
                return op0.value

            if idaapi.IDA_SDK_VERSION >= 600:
                op1 = idautils.DecodeInstruction(instruction)[1]
            else:
                op1 = idaapi.get_instruction_operand(instruction, 1)

            if op1.value and op1.type == o_imm and GetStringType(
                    self.ea) == None:
                return op1.value

        return None
示例#8
0
def get_op(ea, op, stkvars=None):
    '''ea_t -> int -> opt:{int : tinfo_t} -> op_ret'''
    cmd = idautils.DecodeInstruction(ea)
    cmd.Operands = get_operands(cmd)  # for mips_op_hack
    op = mips_op_hack(cmd, op)
    opd = cmd[op]

    if opd.type == idaapi.o_reg:  # gpr, XXX sorta MIPS-specific
        return op_ret(op_ty.reg, regs.gpr(opd.reg), 0)
    elif opd.type == idaapi.o_idpspec1:  # fpr, XXX sorta MIPS-specific
        return op_ret(op_ty.reg, regs.fpr(opd.reg), 0)
    elif opd.type in [idaapi.o_near, idaapi.o_mem]:
        return op_ret(op_ty.name, idc.Name(opd.addr), 0)
    elif idc.isStkvar1(idc.GetFlags(ea)):
        # IDA seems to set this flag even for operands beyond the second,
        # i.e. both of these are true for isStkvar1:
        # .text:10003A84                 sd      $a1, 0x2E0+var_58($sp)
        # .text:10003A68                 addiu   $a1, $sp, 0x2E0+var_2D8
        try:
            func = idaapi.get_func(ea)
            off = idaapi.calc_stkvar_struc_offset(func, ea, op)
            (name, ti) = stkvars[off]

            return op_ret_for_ti(ti, name, off, off)
        except KeyError:
            raise OperandUnresolvableError('unable to get operand %u at %s' %
                                           (op, idc.atoa(ea)))
    elif opd.type in [idaapi.o_imm, idaapi.o_displ]:
        return cpu_ida.ida_current_cpu().data.get_op_addrmode(ea, op, cmd)
    else:
        raise OperandUnresolvableError('unable to get operand %u at %s' %
                                       (op, idc.atoa(ea)))
示例#9
0
 def __mark_bbls(self):
     for thread in self["mem_areas"][0]['threads']:
         for bbl in thread['bbls']:
             ea = bbl['start']
             for _ in range(bbl['inst']):
                 idaapi.set_item_color(ea, 0x49feaf)
                 ea += idautils.DecodeInstruction(ea).size
示例#10
0
    def _collect_all(self):
        """
        Calls the attributes' Collect functions, once for attributes in
        ATTRS_COLLECTED_ONCE and for each instruction in for attributes in
        ATTR_COLLECTED_ITER.
        """
        collect_args = {"first_addr": self._first_addr}
        # Attributes that don't need to iterate instructions.
        for one_attribute in ATTRS_COLLECTED_ONCE.keys():
            getattr(self, one_attribute)._collect_data(collect_args)

        # Attributes which need to iterate instructions. Iterate over
        # instructions, while each attribute extracts data from it.
        for i in range(len(self._func_items)):

            func_item = self._func_items[i]
            ins = idautils.DecodeInstruction(func_item)
            ins_type = ins.itype
            ins_operands = redb_client_utils.collect_operands_data(func_item)

            collect_args["func_item"] = func_item
            collect_args["ins_type"] = ins_type
            collect_args["ins_operands"] = ins_operands

            for one_attribute in ATTR_COLLECTED_ITER.keys():
                getattr(self, one_attribute)._collect_data(collect_args)
示例#11
0
    def jumps_to(f, t):
        f_ea = idc.LocByName(f)
        t_ea = idc.LocByName(t)

        for start, end in idautils.Chunks(f_ea):
            ea = start
            while (ea < end):
                i = idautils.DecodeInstruction(ea)

                #Functions have data chunks in them, these are offsets and dwords. skipping 4 ahead seems like a safe choice.
                if type(i) == type(None):
                    ea += 4
                    continue

                #detect if instruction is a jump to t_ea
                m = idc.GetMnem(ea)
                if idc.GetMnem(ea) == "LDR" and idc.GetOpnd(
                        ea, 0) == "PC" and t in idc.GetOpnd(ea, 1):
                    return True
                elif idc.GetMnem(ea) == "BX" and idc.GetOpnd(ea, 0) == t:
                    return True

                try:
                    ea += i.size
                except:
                    print "0x%08x" % ea
                    print "DecodeInstruction failed!"
                    print i.size

        return False
示例#12
0
 def activate(self, ctx):
     screen_ea = idaapi.get_screen_ea()
     gen_xrefs = idautils.XrefsTo(screen_ea, 0)
     for xx in gen_xrefs:
         ref_loc = xx.frm
         print("Creating switch idiom at ea: ", hex(ref_loc))
         jmp_loc = ref_loc + 14
         print("Jump instruction should be at: ", hex(jmp_loc))
         ins = idautils.DecodeInstruction(jmp_loc)
         name = ins.get_canon_mnem()
         if name != "jmp":
             print("Warning found instruction ", name)
             continue
         if ins.Op1.type != idaapi.o_reg:
             print("Warning found non reg as operand")
             continue
         reg_num = ins.Op1.reg
         reg_name = idaapi.get_reg_name(reg_num, 8)
         print("Jump register is named ", reg_name)
         s = idaapi.switch_info_t()
         s.flags |= idaapi.SWI_SIGNED | idaapi.SWI_ELBASE
         s.elbase = screen_ea
         s.set_jtable_element_size(4)
         s.ncases = 6
         s.set_expr(reg_num, 7)
         s.jumps = screen_ea
         s.startea = jmp_loc
         idaapi.set_switch_info(jmp_loc, s)
         idaapi.create_switch_table(jmp_loc, s)
     return 1
示例#13
0
def is_jump_plus_one(ea):
    """
    like:

        .text:00401089                 jmp     short loc_40108C
        .text:00401089 ; ---------------------------------------------------------------------------
        .text:0040108B                 db 0BAh ; º
        .text:0040108C ; ---------------------------------------------------------------------------
        .text:0040108C
        .text:0040108C loc_40108C:                             ; CODE XREF: .text:00401089↑j
        .text:0040108C                 mov     eax, 1
    """
    insn = idautils.DecodeInstruction(ea)
    if insn is None:
        logger.debug("0x%x: failed to decode instruction", ea)
        return False, None

    if insn.get_canon_mnem() != "jmp":
        return False, None

    next_ea = insn.ea + insn.size
    if insn.ops[0].addr != next_ea + 1:
        return False, None

    return True, insn.size + 1
示例#14
0
    def jump_branches(self, ea):
        """ if this instruction is a jump, yield the destination(s)
            of the jump, of which there may be more than one.
            
            only literal destinations (i.e. addresses without dereferences)
            are yielded. """

        mnem = idc.GetMnem(ea)
        insn = idautils.DecodeInstruction(ea)

        if mnem in self.unconditional_jumps:

            if insn.Op1.type == idaapi.o_near:

                if insn.Op1.addr > self.signed_limit:
                    dest = -((self.max_int + 1) - op.addr)
                else:
                    dest = insn.Op1.addr

                yield dest

        elif mnem in self.conditional_jumps:
            dest = insn.Op1.addr
            yield dest
            dest = ea + insn.size
            yield dest

        return
示例#15
0
    def activate(self, ctx):
        # print("ctx.cur_ea : 0x%x" % ctx.cur_ea)
        # print("ctx.cur_extracted_ea : 0x%x" % ctx.cur_extracted_ea)

        # Extract selected enum
        instruction = idc.GetDisasm(ctx.cur_ea)
        selection = ctx.cur_extracted_ea

        # correctly parse the selected value as int (hex or decimal)
        # since ctx.cur_extracted_ea has a bug (IDA always consider
        # the selected value as hex)
        if instruction.find("{0:X}h".format(selection)) != -1:
            # print("hex value found !")
            selected_value = ctx.cur_extracted_ea
        elif instruction.find("{0:d}".format(selection)) != -1:
            # print("int value found !")
            selected_value = int("%x" % ctx.cur_extracted_ea)
        else:
            # print("nothing selected !")
            return 1

        # next power of two for masking
        selected_value_mask = self.shift_bit_length(selected_value) - 1
        # print("selected_value : 0x%X" % selected_value)
        # print("selected_value mask : 0x%X" % selected_value_mask)

        # query magnum db
        url = SearchMagicNumber.MAGNUMDB_QUERY.format(
            value=selected_value, key=SearchMagicNumber.MAGNUMDB_KEY)
        answer = urlopen(url)
        results = json.loads(answer.read())

        # Let the user select the best answer
        c = ChooseMagicNumber(selected_value, results["Items"])
        selected_index = c.Show(modal=True)
        if selected_index < 0:
            return

        # Apply the newly found enum
        selected_item = results["Items"][selected_index]
        selected_name = selected_item["Title"].encode('ascii')
        selected_value = int(selected_item["Value"])

        # serial is important since several entries can have the same value
        entryid, serial = self._manager.add_magnumdb_entry(
            selected_name, selected_value)

        # locate the operand where to apply the enum
        insn = idautils.DecodeInstruction(ctx.cur_ea)
        for op in filter(lambda o: o.type == idaapi.o_imm, insn.Operands):

            # heuristic : the selected immediate is the first in the instruction with
            # the same exact value (we are using a mask since IDA loves to set FFFFFFFF to high words)
            if op.value & selected_value_mask == selected_value:
                # Apply the enum
                idc.OpEnumEx(ctx.cur_ea, op.n,
                             idaapi.get_enum("_IDA_MAGNUMDB"), serial)
                break

        return 1
示例#16
0
文件: Fentanyl.py 项目: zha0/Fentanyl
 def togglejump(self, ea):
     """ Toggle jump condition """
     inst = idautils.DecodeInstruction(ea)
     mnem = inst.get_canon_mnem()
     if mnem not in self.JUMPS: return False
     return self.assemble(
         ea, [idc.GetDisasm(ea).replace(mnem, self.JUMPS[mnem])])
示例#17
0
文件: util.py 项目: d-ned/mcsema
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 = idautils.DecodeInstruction(ea)
    if not decoded_inst:
        _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
示例#18
0
def stringify():
    ea = idc.here()
    size_data = get_bitness_bytes(ea)
    f = idaapi.get_func(ea)
    frsize = idc.GetFrameLvarSize(ea)
    position = f.startEA
    size = 0
    while position < f.endEA:
        instr = idautils.DecodeInstruction(position)
        if instr is None:
            print("%x: Not and instruction found" % position)
            break
        mnem = instr.get_canon_mnem()
        if mnem == "mov":
            if instr.Op2.type == idaapi.o_imm and instr.Op1.type == idaapi.o_reg:  #this may be string load
                is_string, size_s = is_this_a_real_string(
                    position + instr.size, instr, size_data)
                if is_string is True:
                    make_string(instr.Op2.value, size_s)
        elif mnem == "lea":
            if instr.Op2.type == idaapi.o_mem and instr.Op1.type == idaapi.o_reg:
                is_string, size_s = is_this_a_real_string(
                    position + instr.size, instr, size_data)
                if is_string is True:
                    make_string(instr.Op2.addr, size_s)
        position += instr.size
示例#19
0
def isLikeLoadJmpTable(ea):
    insn_t = idautils.DecodeInstruction(ea)

    # 1) mov reg, off[reg*4]
    if hasDispl(insn_t, 1):
        base, scale, index, displ = getAddressParts(insn_t, 1)
        if base == 5 and scale == 2 and idc.isData(idc.GetFlags(displ)):
            # check if there is a table of valid code pointers
            ncases = 0
            bs = idaapi.get_many_bytes(displ, 4)
            if bs == None or len(bs) != 4:
                return False

            jmpaddress = struct.unpack('<I', bs)[0]
            while idc.isCode(idc.GetFlags(jmpaddress)):
                ncases += 1
                bs = idaapi.get_many_bytes(displ+ncases*4, 4)
                if bs == None or len(bs) != 4:
                    break
                jmpaddress = struct.unpack('<I', bs)[0]

            if ncases != 0:
                return True

    return False
 def lookForOpArgs(self, start, end):
     for head in idautils.Heads(start, end):
         try:
             for i in range(2):
                 if using_ida7api:
                     t = idc.get_operand_type(head, i)
                 else:
                     t = idc.GetOpType(head, i)
                 if t == idc.o_imm:
                     if using_ida7api:
                         opval = idc.get_operand_value(head, i)
                         insn = idautils.DecodeInstruction(head)
                         opmask = OPERAND_MASK.get(insn.ops[i].dtype)
                         if opmask:
                             opval = opval & opmask
                     else:
                         opval = idc.GetOperandValue(head, i)
                     if self.params.useXORSeed:
                         opval = opval ^ self.params.XORSeed
                     for h in self.params.hashTypes:
                         hits = self.dbstore.getSymbolByTypeHash(
                             h.hashType, opval)
                         for sym in hits:
                             logger.info("0x%08x: %s", head, str(sym))
                             self.addHit(head, sym)
                             self.markupLine(head, sym,
                                             self.params.useDecompiler)
         except Exception as err:
             logger.exception("Exception: %s", str(err))
示例#21
0
def apply_struct(start, end, reg_name, struct_name):
    offsets, operands = infer_struct_offsets(start, end, reg_name)

    sid = get_struct(struct_name)

    for ea, n in operands:
        insn = idautils.DecodeInstruction(ea)
        idc.op_stroff(insn, n, sid, 0)
示例#22
0
def code_score(start_ea, end_ea):
    code_count = 0
    total_count = 0
    for ea in range(start_ea, end_ea, 4):
        if idautils.DecodeInstruction(ea):
            code_count += 1
        total_count += 1
    return float(code_count) / total_count, total_count
示例#23
0
def _instructions_by_count(pc, count):
    """A generator to iterate over a specified number of instructions."""
    for i in xrange(count):
        insn = idautils.DecodeInstruction(pc)
        if insn is None:
            break
        yield insn
        pc += insn.size
示例#24
0
    def __init__(self, ea):
        self._ea = ea
        self._insn = idautils.DecodeInstruction(ea)

        if self._insn is None:
            raise exceptions.SarkNoInstruction("No Instruction at 0x{:08X}.".format(ea))

        self._operands = self._make_operands()
示例#25
0
def instruction_data(func_item):
    """
    Returns an integer representing the instruction.
    """
    func_item_size = idautils.DecodeInstruction(func_item).size
    cmd_data = 0
    for i in idaapi.get_many_bytes(func_item, func_item_size):
        cmd_data = (cmd_data << 8) + ord(i)
    return cmd_data
示例#26
0
def is_jmp_ret(ea):
    """
    like:

        .text:004010C9                 call    $+5
        .text:004010CE                 add     dword ptr [esp], 6
        .text:004010D2                 retn
        .text:004010D2 ; ---------------------------------------------------------------------------
        .text:004010D3                 db  7Dh ; }
        .text:004010D4 ; ---------------------------------------------------------------------------
        .text:004010D4                 mov     eax, 0
    """
    insn = idautils.DecodeInstruction(ea)
    if insn is None:
        return False, None

    if insn.get_canon_mnem() != "call":
        return False, None

    next_ea = insn.ea + insn.size
    if insn.ops[0].addr != next_ea:
        return False, None

    insn = idautils.DecodeInstruction(next_ea)
    if insn is None:
        return False, None

    if insn.get_canon_mnem() != "add":
        return False, None

    delta = insn.ops[1].value
    target = next_ea + delta

    next_ea = insn.ea + insn.size

    insn = idautils.DecodeInstruction(next_ea)
    if insn is None:
        return False, None

    if insn.get_canon_mnem() != "retn":
        return False, None

    return True, target - ea
示例#27
0
def isJmpTable(ea):
    insn_t = idautils.DecodeInstruction(ea)
    is_jmp = insn_t.itype in [idaapi.NN_jmp, idaapi.NN_jmpfi, idaapi.NN_jmpni]

    if not is_jmp: return False

    if idaapi.get_switch_info_ex(ea):
        return True

    return False
示例#28
0
    def get_operand_expression(self, ea, n):
        """ return an expression representing the 'n'-th operand of the instruction at 'ea'. """

        insn = idautils.DecodeInstruction(ea)
        op = insn[n]

        if op.type == idaapi.o_reg:  #  General Register (al,ax,es,ds...)    reg
            sz = self.get_operand_size(op)
            expr = regloc_t(op.reg, sz)

        elif op.type == idaapi.o_mem:  #  Direct Memory Reference  (DATA)

            addr = self.as_signed(op.addr)

            if self.has_sib_byte(op):

                reg = self.get_sib_scaled_index_reg(op)
                # *(addr+reg*scale)
                expr = deref_t(add_t(value_t(addr), \
                    mul_t(regloc_t(reg, self.get_register_size(reg)), \
                        value_t(self.get_sib_scale(op), 8))), self.get_operand_size(op))
            else:
                expr = deref_t(value_t(addr, self.address_size),
                               self.get_operand_size(op))

        elif op.type == idaapi.o_phrase:  #  Memory Ref [Base Reg + Index Reg]

            expr = regloc_t(op.reg, self.get_register_size(op.reg))
            expr = deref_t(expr, self.get_operand_size(op))

        elif op.type == idaapi.o_displ:  #  Memory Reg [Base Reg + Index Reg + Displacement] phrase+addr

            addr = self.as_signed(op.addr)

            expr = regloc_t(op.reg, self.get_register_size(op.reg))

            expr = add_t(expr, value_t(addr, self.address_size))
            expr = deref_t(expr, self.get_operand_size(op))

        elif op.type == idaapi.o_imm:  #  Immediate Value

            _value = self.as_signed(op.value)
            expr = value_t(_value, self.get_operand_size(op))

        elif op.type == idaapi.o_near:  #  Immediate Far Address  (CODE)

            addr = self.as_signed(op.addr)
            expr = value_t(addr, self.get_operand_size(op))
        else:
            #~ print hex(ea),
            raise RuntimeError('%x: unhandled operand type: %s %s' %
                               (ea, repr(op.type), repr(idc.GetOpnd(ea, 1))))
            return

        return expr
示例#29
0
def is_this_a_real_string(next_pos, instr, size_data):
    #Common scenario is when we mov offset into register
    #and after that either fill local string variable or push string as argument
    #so we just check that we use esp 
    next_instr = idautils.DecodeInstruction(next_pos)
    if next_instr.get_canon_mnem() == "mov":
        is_stack_used, ptr_addr = parseOp(next_instr.Op1)
        if is_stack_used is True:
            #Check if we really place our offset
            if next_instr.Op2.type == idaapi.o_reg and next_instr.Op2.reg == instr.Op1.reg: 
                next_pos += next_instr.size
                next_instr = idautils.DecodeInstruction(next_pos)
                if next_instr.get_canon_mnem() == "mov":
                    is_stack_used, size_addr = parseOp(next_instr.Op1)
                    #if we filling string or at least smthng looking very similar
                    if is_stack_used is True and (size_addr - ptr_addr == size_data):
                        #for now explicitly set 0x1000 as max string size
                        if next_instr.Op2.type == idaapi.o_imm and next_instr.Op2.value < 0x1000:
                            return True, next_instr.Op2.value
    return False, 0
示例#30
0
 def assemble(self, ea, cs, ip, use32, line):
     line = line.strip()
     if line == "xor eax, eax":
         return "\x33\xC0"
     elif line == "nop":
         # Decode current instruction to figure out its size
         cmd = idautils.DecodeInstruction(ea)
         if cmd:
             # NOP all the instruction bytes
             return "\x90" * cmd.size
     return None