Beispiel #1
1
    def __init__(self, ea):
        self.ea = ea
        self.funcname_or_segname = ""
        self.text = ""
        if not ida_bytes.is_code(ida_bytes.get_flags(ea)):
            ida_ua.create_insn(ea)

        # text
        t = ida_lines.generate_disasm_line(ea)
        if t:
            self.text = ida_lines.tag_remove(t)

        # funcname_or_segname
        n = ida_funcs.get_func_name(ea) \
            or ida_segment.get_segm_name(ida_segment.getseg(ea))
        if n:
            self.funcname_or_segname = n
def is_code(va):
    if is_head(va):
        flags = idc.get_full_flags(va)
        return ida_bytes.is_code(flags)
    else:
        head = get_head(va)
        return is_code(head)
Beispiel #3
0
def restore_x(unique_name=None, start=None):
    ea = ida_kernwin.get_screen_ea()

    # signature
    if not unique_name:
        if not start:
            seg = ida_segment.getseg(ea)
            start = seg.start_ea
        sig_bytes = ida_bytes.get_bytes(start, SIGNATURE_SIZE)
        sig_hash = hashlib.md5(sig_bytes).hexdigest()
        unique_name = sig_hash

    if not start:
        seg = ida_segment.getseg(ea)
        start = seg.start_ea

    if MD5_hash_data_file and os.path.isfile(MD5_hash_data_file):
        with open(MD5_hash_data_file, "rb") as ifile:
            received_data = pickle.loads(ifile.read())
            saved_data = received_data

            print("dumpDyn::restore\n\
            Name: {}\n\
            Restore address: {}\n".format(unique_name, hex(start)))

            # (start_addr, end_addr, names, comms, bpts, funcs)
            if unique_name in saved_data:
                current_data = saved_data[unique_name]

                # restore names
                names = current_data[2]

                for name in names:
                    # names: (rel_addr, name, is_code)
                    ida_name.set_name(start + name[0], name[1])
                    flags = ida_bytes.get_flags(start + name[0])
                    if name[2] and not ida_bytes.is_code(flags):
                        ida_auto.auto_make_code(start + name[0])

                # restore comments
                # comms: (rel_addr, TYPE, comment)
                comms = current_data[3]
                for comm in comms:
                    # 0:MakeComm and 1:MakeRptCmt
                    ida_bytes.set_cmt(start + comm[0], comm[2], comm[1])

                # restore breakpoints
                # bpts: (rel_addr, size, type)
                bpts = current_data[4]
                for bpt in bpts:
                    ida_dbg.add_bpt(start + bpt[0], bpt[1], bpt[2])

                # restore functions
                funcs_addr = current_data[5]
                for addr in funcs_addr:
                    ida_auto.auto_make_proc(start + addr)  # make code & func
Beispiel #4
0
 def getBlocks(self, function_offset):
     blocks = []
     function_chart = ida_gdl.FlowChart(ida_funcs.get_func(function_offset))
     for block in function_chart:
         extracted_block = []
         for instruction in idautils.Heads(block.start_ea, block.end_ea):
             if ida_bytes.is_code(ida_bytes.get_flags(instruction)):
                 extracted_block.append(instruction)
         if extracted_block:
             blocks.append(extracted_block)
     return sorted(blocks)
Beispiel #5
0
 def postprocess_action(self):
     self._plugin.logger.debug("postprocess_action()")
     if len(self.actions):
         name, ea = self.actions.pop()
         if name == "MakeUnknown":
             flags = ida_bytes.get_full_flags(ea)
             if ida_bytes.is_unknown(flags):
                 self._send_packet(evt.MakeUnknown(ea))
         elif name == "MakeCode":
             flags = ida_bytes.get_full_flags(ea)
             if ida_bytes.is_code(flags):
                 self._send_packet(evt.MakeCodeEvent(ea))
Beispiel #6
0
    def _has_code(self):
        """
        Checks if any address in the changed data area has code in it

        :return: (int) address of the code start, or None.
        """
        for i in xrange(self.data):
            maybe_start_of_item = ida_bytes.get_item_head(self.address + i)
            if ida_bytes.is_code(
                    ida_bytes.get_full_flags(maybe_start_of_item)):
                return self.address + i
        return None
Beispiel #7
0
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))
Beispiel #8
0
def get_stacked_bytes(dec_func_addr):
    func_stacked_bytes_addr_dict = {}
    xrefs = idautils.CodeRefsTo(dec_func_addr, 0)

    for xref in xrefs:
        prev_addr = idc.prev_head(xref)
        prev_addr_2 = idc.prev_head(prev_addr)

        if idc.print_insn_mnem(prev_addr_2) == "call":
            func_name = idc.print_operand(prev_addr_2, 0)
            func_addr = idc.get_name_ea_simple(func_name)
            func_stacked_bytes_addr_dict[xref] = func_addr

    # enc_mod_addr = list(set(enc_mod_addr)) # [Debug] Get unique functions only

    for xref, stacked_bytes_addr in func_stacked_bytes_addr_dict.items():
        print(f"Address: {hex(stacked_bytes_addr)}")
        func_ea = idc.get_func_attr(stacked_bytes_addr, idc.FUNCATTR_START)
        bytes_collected = bytearray()  # Collected stack string store here

        for ins in idautils.FuncItems(func_ea):
            if ida_bytes.is_code(ida_bytes.get_full_flags(ins)):
                if idc.print_insn_mnem(ins) == "mov":
                    if idc.get_operand_type(ins, 1) == idc.o_imm:
                        # disasm = idc.GetDisasm(ins) # [Debug]
                        hex_str_len = len(
                            idc.print_operand(ins, 1).lstrip("0").rstrip("h"))
                        const_hex_byte = idc.print_operand(
                            ins, 1).lstrip("0").rstrip("h")

                        if hex_str_len != 8:  # Skip if const hex byte less than 8
                            append_zero = "0" * (8 - hex_str_len)
                            const_hex_byte = append_zero + const_hex_byte
                            # print(struct.pack("<I", int(const_hex_byte, 16))) # [Debug]

                        # else:
                        # print(struct.pack("<I", int(const_hex_byte, 16))) # [Debug]
                        bytes_collected += struct.pack("<I",
                                                       int(const_hex_byte, 16))

        if len(bytes_collected) >= 1:
            cmt_str = ""
            if dec_func_addr == 0x10001253:  # fn_name_addr
                print(f"{decode_fnname(bytes_collected[4:])}")
                cmt_str = decode_fnname(bytes_collected[4:])
            elif dec_func_addr == 0x1000122B:  # mod_name_addr
                print(f"{decode_modname(bytes_collected[4:])}")
                cmt_str = decode_modname(bytes_collected[4:])
            idc.set_cmt(xref, cmt_str, 1)  # Comment near xref decoder function
        else:
            print(f"[-] {hex(stacked_bytes_addr)} addr error")
def _convert_address_to_function(func):
    """Convert an address that IDA has classified incorrectly into a proper function."""
    # If everything goes wrong, we'll try to restore this function.
    orig = idc.first_func_chunk(func)
    # If the address is not code, let's undefine whatever it is.
    if not ida_bytes.is_code(ida_bytes.get_full_flags(func)):
        if not is_mapped(func):
            # Well, that's awkward.
            return False
        item = ida_bytes.get_item_head(func)
        itemend = ida_bytes.get_item_end(func)
        if item != idc.BADADDR:
            _log(1, 'Undefining item {:#x} - {:#x}', item, itemend)
            ida_bytes.del_items(item, ida_bytes.DELIT_EXPAND)
            idc.create_insn(func)
            # Give IDA a chance to analyze the new code or else we won't be able to create a
            # function.
            #ida_auto.auto_wait()
            autoanalyze()
            idc.plan_and_wait(item, itemend)
    else:
        # Just try removing the chunk from its current function. IDA can add it to another function
        # automatically, so make sure it's removed from all functions by doing it in loop until it
        # fails.
        for i in range(1024):
            if not idc.remove_fchunk(func, func):
                break
    # Now try making a function.
    if ida_funcs.add_func(func) != 0:
        return True
    # This is a stubborn chunk. Try recording the list of chunks, deleting the original function,
    # creating the new function, then re-creating the original function.
    if orig != idc.BADADDR:
        chunks = list(idautils.Chunks(orig))
        if ida_funcs.del_func(orig) != 0:
            # Ok, now let's create the new function, and recreate the original.
            if ida_funcs.add_func(func) != 0:
                if ida_funcs.add_func(orig) != 0:
                    # Ok, so we created the functions! Now, if any of the original chunks are not
                    # contained in a function, we'll abort and undo.
                    if all(idaapi.get_func(start) for start, end in chunks):
                        return True
            # Try to undo the damage.
            for start, _ in chunks:
                ida_funcs.del_func(start)
    # Everything we've tried so far has failed. If there was originally a function, try to restore
    # it.
    if orig != idc.BADADDR:
        _log(0, 'Trying to restore original function {:#x}', orig)
        ida_funcs.add_func(orig)
    return False
Beispiel #10
0
def show_microcode():
    """Generates and displays microcode for an address range.
    An address range can be a selection of code or that of
    the current function."""
    sel, sea, eea = kw.read_range_selection(None)
    pfn = ida_funcs.get_func(kw.get_screen_ea())
    if not sel and not pfn:
        return (False, "Position cursor within a function or select range")

    if not sel and pfn:
        sea = pfn.start_ea
        eea = pfn.end_ea

    addr_fmt = "%016x" if ida_ida.inf_is_64bit() else "%08x"
    fn_name = (ida_funcs.get_func_name(pfn.start_ea) if pfn else "0x%s-0x%s" %
               (addr_fmt % sea, addr_fmt % eea))
    F = ida_bytes.get_flags(sea)
    if not ida_bytes.is_code(F):
        return (False, "The selected range must start with an instruction")

    text, mmat, mba_flags = ask_desired_maturity()
    if text is None and mmat is None:
        return (True, "Cancelled")

    if not sel and pfn:
        mbr = hr.mba_ranges_t(pfn)
    else:
        mbr = hr.mba_ranges_t()
        mbr.ranges.push_back(ida_range.range_t(sea, eea))

    hf = hr.hexrays_failure_t()
    ml = hr.mlist_t()
    mba = hr.gen_microcode(mbr, hf, ml, hr.DECOMP_WARNINGS, mmat)
    if not mba:
        return (False, "0x%s: %s" % (addr_fmt % hf.errea, hf.desc()))
    vp = printer_t()
    mba.set_mba_flags(mba_flags)
    mba._print(vp)
    mcv = microcode_viewer_t()
    if not mcv.Create(
            mba, "0x%s-0x%s (%s)" %
        (addr_fmt % sea, addr_fmt % eea, text), text, fn_name, vp.get_mc()):
        return (False, "Error creating viewer")

    mcv.Show()
    return (True, "Successfully generated microcode for 0x%s..0x%s" %
            (addr_fmt % sea, addr_fmt % eea))
Beispiel #11
0
    def __init__(self, ea):
        self.ea = ea
        self.funcname_or_segname = ""
        self.text = ""
        if not ida_bytes.is_code(ida_bytes.get_flags(ea)):
            ida_ua.create_insn(ea)

        # text
        t = ida_lines.generate_disasm_line(ea)
        if t:
            self.text = ida_lines.tag_remove(t)

        # funcname_or_segname
        n = ida_funcs.get_func_name(ea) \
            or ida_segment.get_segm_name(ida_segment.getseg(ea))
        if n:
            self.funcname_or_segname = n
Beispiel #12
0
    def get_custom_viewer_hint(self, view, place):
        try:
            widget = ida_kernwin.get_current_widget()
            if ida_kernwin.get_widget_type(widget) != ida_kernwin.BWN_DISASM:
                return None

            curline = ida_kernwin.get_custom_viewer_curline(view, True)

            # sometimes get_custom_viewer_place() returns [x, y] and sometimes [place_t, x, y].
            # we want the place_t.
            viewer_place = ida_kernwin.get_custom_viewer_place(view, True)
            if len(viewer_place) != 3:
                return None

            _, x, y = viewer_place
            ea = place.toea()

            # "color" is a bit of misnomer: its the type of the symbol currently hinted
            color = get_color_at_char(curline, x)
            if color != ida_lines.COLOR_ADDR:
                return None

            # grab the FAR references to code (not necessarilty a branch/call/jump by itself)
            far_code_references = [
                xref.to for xref in idautils.XrefsFrom(ea, ida_xref.XREF_FAR)
                if ida_bytes.is_code(ida_bytes.get_flags(xref.to))
            ]
            if len(far_code_references) != 1:
                return None

            fva = far_code_references[0]

            # ensure its actually a function
            if not idaapi.get_func(fva):
                return None

            # this magic constant is the number of "important lines" to display by default.
            # the remaining lines get shown if you scroll down while the hint is displayed, revealing more lines.
            return render_function_hint(fva), DEFAULT_IMPORTANT_LINES_NUM
        except Exception as e:
            logger.warning(
                'unexpected exception: %s. Get in touch with @williballenthin.',
                e,
                exc_info=True)
            return None
Beispiel #13
0
    def get_custom_viewer_hint(self, viewer, place):
        widget_type = ida_kernwin.get_widget_type(viewer)
        if widget_type != ida_kernwin.BWN_DISASM:
            return

        flags = ida_bytes.get_flags(place.toea()) if place else 0
        if not ida_bytes.is_code(flags):
            return

        item = AMIE.extract_item(viewer)
        if not item:
            return
        tag, val = item

        hint = self.arch.hint(place.toea(), tag, val)
        if not hint:
            return

        return AMIE.format_hint(*hint)
def main():

    typelib = None
    for typelib_name in DEFAULT_TYPELIBS:
        typelib = ida_typeinf.load_til(typelib_name)
        if typelib:
            break
    if not typelib:
        print(f"Unable to load mssdk")
        return
    # print(f"Loaded mssdk type library: {typelib.name}")

    status_enum = ida_typeinf.import_type(typelib, -1, "MACRO_STATUS")
    if status_enum == ida_netnode.BADNODE:
        print(f"Unable to load type MACRO_STATUS")
    # print(f"Loaded MACRO_STATUS")

    # Grab the enum members
    enum_map = get_enum_map(status_enum)
    cur_member_id = ida_enum.get_first_enum_member(status_enum)
    while cur_member_id:
        cur_value = idaapi.get_const_value(cur_member_id)
        enum_map[cur_value] = cur_member_id
        cur_member_id = ida_enum.get_next_enum_member(cur_member_id)

    # Iterate over all untyped immediates
    imm_ea = ida_ida.cvar.inf.min_ea
    while (imm_ea != idaapi.BADADDR):
        imm_ea = ida_search.find_notype(
            imm_ea, ida_search.SEARCH_NEXT | ida_search.SEARCH_DOWN)[0]
        if ida_bytes.is_code(ida_bytes.get_flags(imm_ea)):
            enum_value = idc.get_operand_value(imm_ea, 1)
            # Only handle likely error types right now..
            if (enum_value & DWORD_MASK) > 0xC0000000:
                try:
                    cid = enum_map[enum_value]
                    # print(f"Applying {hex(enum_value & DWORD_MASK)} at {hex(imm_ea)}")
                    # We don't need the member, we can just apply the enum type to the address
                    ida_bytes.op_enum(imm_ea, 1, status_enum, 0)
                except KeyError:
                    continue
Beispiel #15
0
    def get_conflict(self):
        """

        :return: None if there's no conflict, empty string if there's no change, data if there's a change.
        """
        # TODO: Fill docstring, plus, make the function return 0,1,2 and save the current data by itself.
        conflicts = ""
        conflict_flag = False
        for i in xrange(self.data):
            current_address = self.address + i
            head_address = ida_bytes.get_item_head(current_address)
            if ida_bytes.is_code(ida_bytes.get_full_flags(head_address)):
                conflict_flag = True
            ea_flags = ida_bytes.get_full_flags(head_address)
            if not ida_bytes.is_data(ea_flags):
                continue
            conflict_flag = True
            conflicts += '%s at 0x%x\n' % (
                self.TYPE_TO_NAME[ea_flags & ida_bytes.DT_TYPE], head_address)

        if conflict_flag:
            return conflicts
        return None
Beispiel #16
0
def color_head(ea):
    flags = ida_bytes.get_flags(ea)
    if not ida_bytes.is_code(flags):
        return

    mnem = ida_ua.print_insn_mnem(ea)
    if mnem == 'call':
        logger.debug('call: 0x%x', ea)
        idc.set_color(ea, idc.CIC_ITEM, CALL_COLOR)
    elif mnem == 'xor':
        if idc.get_operand_value(ea, 0) != idc.get_operand_value(ea, 1):
            logger.debug('non-zero xor: 0x%x', ea)
            idc.set_color(ea, idc.CIC_ITEM, ENCRYPT_COLOR)
    elif mnem in ('sdit', 'sgdt', 'sldt', 'smsw', 'str', 'in', 'cpuid'):
        logger.debug('anti-vm: 0x%x', ea)
        idc.set_color(ea, idc.CIC_ITEM, ANTIANALYSIS_COLOR)
    elif mnem == 'in':
        if idc.get_operand_value(ea, 0) in ("3", "2D"):
            logger.debug('anti-debug: 0x%x', ea)
            idc.set_color(ea, idc.CIC_ITEM, ANTIANALYSIS_COLOR)
    elif mnem in ('rdtsc', 'icebp'):
        logger.debug('anti-debug: 0x%x', ea)
        idc.set_color(ea, idc.CIC_ITEM, ANTIANALYSIS_COLOR)
Beispiel #17
0
def save_x(unique_name=None, start=None, size=None):
    ea = ida_kernwin.get_screen_ea()

    # signature
    if not unique_name:
        if not start:
            seg = ida_segment.getseg(ea)
            start = seg.start_ea
        sig_bytes = ida_bytes.get_bytes(start, SIGNATURE_SIZE)
        sig_hash = hashlib.md5(sig_bytes).hexdigest()
        unique_name = sig_hash

    if not start or not size:
        seg = ida_segment.getseg(ea)
        start = seg.start_ea
        size = seg.size()

    # (start_addr, end_addr, names, comms)
    saved_data = {}
    if MD5_hash_data_file and os.path.isfile(MD5_hash_data_file):
        with open(MD5_hash_data_file, "rb") as ifile:
            received_data = pickle.loads(ifile.read())
            if received_data:
                saved_data = received_data

    # save names (func_names, labels, etc)
    # (addr, name, is_code)
    names_addr_name = []
    names = idautils.Names()
    for addr, name in names:
        if start <= addr <= start + size:
            flags = ida_bytes.get_flags(addr)
            names_addr_name.append(
                (addr - start, name, ida_bytes.is_code(flags)))

    # save comments
    comms_addr_type_comm = []
    # (addr, TYPE, comment)
    # type 0:comment 1:rpt_comment
    end = start + size
    for i in range(start, end + 1):
        if ida_bytes.get_cmt(i, 0):  # 0 Comment
            comms_addr_type_comm.append((i - start, 0, ida_bytes.get_cmt(i,
                                                                         0)))
        if ida_bytes.get_cmt(i, 1):  # 1 RptCmt
            comms_addr_type_comm.append((i - start, 1, ida_bytes.get_cmt(i,
                                                                         1)))

    # breakpoints
    bpts_addr_size_type = []
    bpt = ida_dbg.bpt_t()
    global remove_on_exit_bpts
    for i in range(start, end + 1):
        if ida_dbg.get_bpt(i, bpt):
            bpts_addr_size_type.append((i - start, bpt.size, bpt.type))
            remove_on_exit_bpts.append(i)

    # functions
    funcs_addr = []
    flag = ida_bytes.get_flags(start)
    if ida_bytes.is_func(flag):
        funcs_addr.append(0)  # start addr
    next_func = ida_funcs.get_next_func(start)
    while next_func:
        funcs_addr.append(next_func.start_ea - start)
        next_func = ida_funcs.get_next_func(next_func.start_ea)

    # SAVE
    saved_data[unique_name] = (start, start + end, names_addr_name,
                               comms_addr_type_comm, bpts_addr_size_type,
                               funcs_addr)

    if MD5_hash_data_file:
        with open(MD5_hash_data_file, "wb") as ifile:
            serial_data = pickle.dumps(saved_data)
            ifile.write(serial_data)
            print("dumpDyn::save:\n\
            Name: {}\n\
            Start address: {}".format(unique_name, hex(start)))
import idautils
import ida_bytes
import idaapi

for ea in idautils.Heads():
    if ida_bytes.is_code(ida_bytes.get_flags(ea)) and idaapi.is_call_insn(ea):
        idaapi.set_item_color(ea, 0xFFFFFFA0)
Beispiel #19
0
def get_all_calls():
    is_64bit = set_version_and_platform_specific_elements()

    call_list = []
    call_addr_list = []

    #check if stack segment is None. It's a problem
    if is_64bit:
        sp = cpu.Rsp
        ip = cpu.Rip
    else:
        sp = cpu.Esp
        ip = cpu.Eip

    if idaapi.getseg(cpu.Rsp) is None:
        warning("Stack segment is None")
        return False

    #information about current fun
    is_current_fun = True
    call_list.append(get_info_about_call(ip, "", sp, is_current_fun))
    call_addr_list.append(ip)

    #iterate by stack
    if is_64bit:
        #at the begging return address is set as a current ip
        return_addr = cpu.Rip
        curr_sp = cpu.Rsp
        curr_bp = cpu.Rbp

        for i in range(0, MAX_NUMBER_FUNCTION_TO_SHOW):
            return_addr, curr_sp, curr_bp = calculate_caller_function_frame_info_x64(
                return_addr, curr_sp, curr_bp)
            if return_addr == idaapi.BADADDR or return_addr == 0:
                break

            curr_segment = idaapi.getseg(return_addr)

            #segmenst must exists and be executable
            if not curr_segment or (curr_segment.perm
                                    & idaapi.SEGPERM_EXEC) == 0:
                continue

            is_call, curr_call_addr = check_previous_inst_is_call(
                return_addr, is_64bit)
            if not is_call:
                continue

            #if bytes are not disassembled, then do it
            flags = ida_bytes.get_full_flags(curr_call_addr)
            if not ida_bytes.is_code(flags):
                idc.create_insn(curr_call_addr)

            #save a call argument
            call_list.append(
                get_info_about_call(curr_call_addr,
                                    print_operand(curr_call_addr, 0),
                                    return_addr))
            call_addr_list.append(curr_call_addr)
    else:
        curr_ebp = cpu.Ebp
        ptr_size = 4
        pfn_get_ptr = idc.get_wide_dword

        for i in range(0, MAX_NUMBER_FUNCTION_TO_SHOW):
            return_addr = pfn_get_ptr(curr_ebp + ptr_size)
            debug('ret: {:08X}'.format(return_addr))
            curr_ebp = pfn_get_ptr(curr_ebp)
            debug('ebp: {:08X}'.format(curr_ebp))

            if return_addr == idaapi.BADADDR or return_addr == 0:
                break

            curr_segment = idaapi.getseg(return_addr)

            #segmenst must exists and be executable
            if not curr_segment or (curr_segment.perm
                                    & idaapi.SEGPERM_EXEC) == 0:
                continue

            is_call, curr_call_addr = check_previous_inst_is_call(
                return_addr, is_64bit)
            if not is_call:
                continue

            #if bytes are not disassembled, then do it
            flags = ida_bytes.get_full_flags(curr_call_addr)
            if not ida_bytes.is_code(flags):
                idc.create_insn(curr_call_addr)

            #save a call argument
            call_list.append(
                get_info_about_call(curr_call_addr,
                                    print_operand(curr_call_addr, 0),
                                    curr_ebp))
            call_addr_list.append(curr_call_addr)

    return True, call_list, call_addr_list
Beispiel #20
0
def is_code(ea):
    flags = ida_bytes.get_full_flags(ea)
    return ida_bytes.is_code(flags) and ida_bytes.is_head(flags)
Beispiel #21
0
def show_xrefs(ea, gco, xrefs, ndefs):
    title = "xrefs to %s at %08x" % (gco.name, ea)
    xc = xref_chooser_t(xrefs, title, ndefs, ea, gco)
    i = xc.Show(True)
    if i >= 0:
        ida_kernwin.jumpto(xrefs[i])


if ida_hexrays.init_hexrays_plugin():
    ea = ida_kernwin.get_screen_ea()
    pfn = ida_funcs.get_func(ea)
    w = ida_kernwin.warning
    if pfn:
        F = ida_bytes.get_flags(ea)
        if ida_bytes.is_code(F):
            gco = ida_hexrays.gco_info_t()
            if ida_hexrays.get_current_operand(gco):
                # generate microcode
                hf = ida_hexrays.hexrays_failure_t()
                mbr = ida_hexrays.mba_ranges_t(pfn)
                mba = ida_hexrays.gen_microcode(mbr, hf, None,
                                                ida_hexrays.DECOMP_WARNINGS,
                                                ida_hexrays.MMAT_PREOPTIMIZED)
                if mba:
                    merr = mba.build_graph()
                    if merr == ida_hexrays.MERR_OK:
                        ncalls = mba.analyze_calls(ida_hexrays.ACFL_GUESS)
                        if ncalls < 0:
                            print(
                                "%08x: failed to determine some calling conventions",
Beispiel #22
0
def dump_heads(out):
    # out is a file like object, sys.stdout or an acual file object

    # There doesn't seem to a good way to determine what function a
    # particular address is in.  Almost everyone recommends iterating
    # of the functions, and then getting the bytes out of each, but
    # that's not really what we want because it skips non function
    # bytes and reports them in the wrong order. It appears that the
    # best we can do is to build a map in advance. :-(
    a2fmap = build_a2fmap()

    min_ea = idaapi.cvar.inf.minEA
    max_ea = idaapi.cvar.inf.maxEA
    ea = min_ea
    while ea != ida_idaapi.BADADDR:
        ida_auto.show_addr(ea)
        isize = ida_bytes.get_item_size(ea)
        ibytes = ida_bytes.get_bytes(ea, isize)
        ihexbytes = binascii.b2a_hex(ibytes).upper()
        iflags = ida_bytes.get_flags(ea)

        # Skip the PE header?
        if not ida_bytes.is_head(iflags):
            ea = ida_bytes.next_head(ea, max_ea)
            continue

        # Loop up this address in the address-to-function map.
        if ea in a2fmap:
            faddrs = a2fmap[ea]
        else:
            faddrs = [ea]

        tcode = "ERROR"
        imnem = "???"
        iops = "???"

        if ida_bytes.is_code(iflags):
            tcode = "INSN"
            imnem = "???"
            iops = "???"

            insn = idautils.DecodeInstruction(ea)
            if insn == None:
                imnem = "BAD"
                iops = ""
            elif not insn.is_canon_insn():
                imnem = "NCAN"
                iops = ""
            else:
                imnem = insn.get_canon_mnem()

                sops = []
                for n in range(8):
                    ostr = ida_ua.print_operand(ea, n)
                    if ostr is not None:
                        ostrnt = ida_lines.tag_remove(ostr)
                        if ostrnt != '':
                            sops.append(ostrnt)
                iops = ', '.join(sops)

        elif ida_bytes.is_data(iflags):
            tcode = "DATA"
            imnem = "db"
            iops = "???"
            if ida_bytes.is_align(iflags):
                tcode += "_ALIGN"
            #elif ida_bytes.is_struct(iflags):
            #    tcode += "_STRUCT"
            #elif ida_bytes.is_char(iflags):
            #    tcode += "_STR"
            # There are other types that IDA recognizes.
        elif ida_bytes.is_unknown(iflags):
            tcode = "UNK-%08X" % iflags
            imnem = "???"
            iops = "???"

        for faddr in sorted(faddrs):
            out.write('"PART",0x%08X,"%s",0x%08X,"%s","%s","%s"\n' %
                      (ea, tcode, faddr, ihexbytes, imnem, iops))
        ea = ida_bytes.next_head(ea, max_ea)
    print "Analysis complete!"
movs = ["mov", "xchg"]

ida_api_is_new = False
try:
    import ida_auto
    ida_api_is_new = True
except ImportError:
    pass

user_pos = ida_kernwin.get_screen_ea()
after_function_before_user_pos = ida_funcs.get_prev_func(user_pos).end_ea + 1
before_function_after_user_pos = ida_funcs.get_next_func(user_pos).start_ea - 1
hopefully_a_sane_start_of_function = (after_function_before_user_pos
                                      & ~0x0F) + 0x10
make_fun_pos = None
if ida_bytes.is_code(ida_bytes.get_flags(hopefully_a_sane_start_of_function)):
    make_fun_pos = hopefully_a_sane_start_of_function


def re_analyze_relevant_range():
    ida_bytes.del_items(
        after_function_before_user_pos, 0,
        before_function_after_user_pos - after_function_before_user_pos)
    if not make_fun_pos is None:
        assume_code_at(make_fun_pos)
    else:
        run_autoanalysis(after_function_before_user_pos,
                         before_function_after_user_pos)


def run_autoanalysis(start, end=None):
Beispiel #24
0
def CallStackWalk(nn):
    class Result:
        """
        Class holding the result of one call stack item
        Each call stack item instance has the following attributes:
            caller = ea of caller
            displ  = display string
            sp     = stack pointer
        """
        def __init__(self, caller, sp):
            self.caller = caller
            self.sp     = sp
            f = ida_funcs.get_func(caller)
            self.displ = "%08x: " % caller
            if f:
                self.displ += ida_funcs.get_func_name(caller)
                t = caller - f.start_ea
                if t > 0: self.displ += "+" + hex(t)
            else:
                self.displ += hex(caller)
            self.displ += " [" + hex(sp) + "]"

        def __str__(self):
            return self.displ

    # get stack pointer
    sp = idautils.cpu.Esp
    seg = ida_segment.getseg(sp)
    if not seg:
        return (False, "Could not locate stack segment!")

    stack_seg = Seg(seg)
    word_size = 2 ** (seg.bitness + 1)
    callers = []
    sp = idautils.cpu.Esp - word_size
    while sp < stack_seg.end_ea:
        sp += word_size
        ptr = next(idautils.GetDataList(sp, 1, word_size))
        seg = ida_segment.getseg(ptr)
        # only accept executable segments
        if (not seg) or ((seg.perm & ida_segment.SEGPERM_EXEC) == 0):
            continue
        # try to find caller
        caller = IsPrevInsnCall(ptr)
        # we have no recognized caller, skip!
        if caller is None:
            continue

        # do we have a debug name that is near?
        if nn:
            ret = nn.find(caller)
            if ret:
                ea = ret[0]
                # function exists?
                f = ida_funcs.get_func(ea)
                if not f:
                    # create function
                    ida_funcs.add_func(ea)

        # get the flags
        f = ida_bytes.get_flags(caller)
        # no code there?
        if not ida_bytes.is_code(f):
            ida_ua.create_insn(caller)

        callers.append(Result(caller, sp))
    #
    return (True, callers)
Beispiel #25
0
def is_code(ea):
    if idaapi.IDA_SDK_VERSION <= 699:
        retval = idc.IsCode(ea)
    else:
        retval = ida_bytes.is_code(ea)
    return retval
 def match(F):
     return ida_bytes.is_code(F) and not ida_bytes.is_flow(F)
Beispiel #27
0
def CallStackWalk(nn):
    class Result:
        """
        Class holding the result of one call stack item
        Each call stack item instance has the following attributes:
            caller = ea of caller
            displ  = display string
            sp     = stack pointer
        """
        def __init__(self, caller, sp):
            self.caller = caller
            self.sp     = sp
            f = ida_funcs.get_func(caller)
            self.displ = "%08x: " % caller
            if f:
                self.displ += ida_funcs.get_func_name(caller)
                t = caller - f.start_ea
                if t > 0: self.displ += "+" + hex(t)
            else:
                self.displ += hex(caller)
            self.displ += " [" + hex(sp) + "]"

        def __str__(self):
            return self.displ

    # get stack pointer
    sp = idautils.cpu.Esp
    seg = ida_segment.getseg(sp)
    if not seg:
        return (False, "Could not locate stack segment!")

    stack_seg = Seg(seg)
    word_size = 2 ** (seg.bitness + 1)
    callers = []
    sp = idautils.cpu.Esp - word_size
    while sp < stack_seg.end_ea:
        sp += word_size
        ptr = next(idautils.GetDataList(sp, 1, word_size))
        seg = ida_segment.getseg(ptr)
        # only accept executable segments
        if (not seg) or ((seg.perm & ida_segment.SEGPERM_EXEC) == 0):
            continue
        # try to find caller
        caller = IsPrevInsnCall(ptr)
        # we have no recognized caller, skip!
        if caller is None:
            continue

        # do we have a debug name that is near?
        if nn:
            ret = nn.find(caller)
            if ret:
                ea = ret[0]
                # function exists?
                f = ida_funcs.get_func(ea)
                if not f:
                    # create function
                    ida_funcs.add_func(ea)

        # get the flags
        f = ida_bytes.get_flags(caller)
        # no code there?
        if not ida_bytes.is_code(f):
            ida_ua.create_insn(caller)

        callers.append(Result(caller, sp))
    #
    return (True, callers)