Esempio n. 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
Esempio n. 2
0
def main():
    # Get current ea
    ea = ida_kernwin.get_screen_ea()

    # Get segment class
    seg = ida_segment.getseg(ea)

    # Loop from segment start to end
    func_ea = seg.start_ea

    # Get a function at the start of the segment (if any)
    func = ida_funcs.get_func(func_ea)
    if func is None:
        # No function there, try to get the next one
        func = ida_funcs.get_next_func(func_ea)

    seg_end = seg.end_ea
    while func is not None and func.start_ea < seg_end:
        funcea = func.start_ea
        print("Function %s at 0x%x" %
              (ida_funcs.get_func_name(funcea), funcea))

        ref = ida_xref.get_first_cref_to(funcea)

        while ref != ida_idaapi.BADADDR:
            print("  called from %s(0x%x)" %
                  (ida_funcs.get_func_name(ref), ref))
            ref = ida_xref.get_next_cref_to(funcea, ref)

        func = ida_funcs.get_next_func(funcea)
Esempio n. 3
0
    def __get_relative_node(self, src_node, key_name):
        src_node_addr = src_node.get_addr()
        next_node_addr = ida_xref.get_first_cref_to(src_node_addr)
        print('[Debug]next_addr 0x%x' % next_node_addr)
        if next_node_addr == idaapi.BADADDR:
            return
        if next_node_addr != idc.PrevHead(src_node_addr):
            new_tree_node = TreeNode(ida_funcs.get_func_name(next_node_addr),
                                     next_node_addr)
            new_tree_node.add_parent(src_node)
            src_node.add_child(new_tree_node)
            print('[*]Add node %s 0x%x' %
                  (new_tree_node.get_name(), new_tree_node.get_addr()))
            self.__get_relative_node(new_tree_node, key_name)

        next_node_addr = ida_xref.get_next_cref_to(src_node_addr,
                                                   next_node_addr)
        print('[Debug]next_addr 0x%x' % next_node_addr)
        while next_node_addr != idaapi.BADADDR:
            if next_node_addr == idc.PrevHead(src_node_addr):
                continue
            new_tree_node = TreeNode(ida_funcs.get_func_name(next_node_addr),
                                     next_node_addr)
            new_tree_node.add_parent(src_node)
            src_node.add_child(new_tree_node)
            print('[*]Add node %s 0x%x' %
                  (new_tree_node.get_name(), new_tree_node.get_addr()))
            self.__get_relative_node(new_tree_node, key_name)
            next_node_addr = ida_xref.get_next_cref_to(src_node_addr,
                                                       next_node_addr)
            print('[Debug]next_addr 0x%x' % next_node_addr)
        return
Esempio n. 4
0
 def gen_sink_func_addr(self):
     for func_addr in idautils.Functions():
         func_name = ida_funcs.get_func_name(func_addr)
         if func_name in self.sink_func_info:
             yield (func_name, func_addr)
         else:
             continue
Esempio n. 5
0
    def btn_func_xref_count(self, code=0):
        """
        函数调用次数统计
        """
        xref_count_dict = OrderedDict()
        for func_addr_t in idautils.Functions():
            count = len(list(idautils.CodeRefsTo(func_addr_t, 0)))
            xref_count_dict[ida_funcs.get_func_name(func_addr_t)] = [
                func_addr_t, count
            ]
        ordered_list = sorted(list(xref_count_dict.items()),
                              key=lambda x: x[1][1],
                              reverse=True)

        cols = [['', 0 | ida_kernwin.Choose.CHCOL_DEC],
                ['函数名', 15 | ida_kernwin.Choose.CHCOL_PLAIN],
                ['地址', 10 | ida_kernwin.Choose.CHCOL_HEX],
                ['次数', 10 | ida_kernwin.Choose.CHCOL_PLAIN]]
        items = []

        for x in ordered_list:
            data = AnalysisChooseData(vuln=0,
                                      name=x[0],
                                      ea=x[1][0],
                                      other1=str(x[1][1]))
            items.append(data)

        chooser = AnalysisChooser(title='函数调用次数统计', cols=cols, item=items)
        chooser.Show()
Esempio n. 6
0
    def visit_expr(self, e):
        if e.op != ida_hexrays.cot_call:
            return 0

        func = e.x
        args = e.a
        if func.op != ida_hexrays.cot_obj:
            return 0

        name = ida_funcs.get_func_name(func.obj_ea)
        if name not in self.targets:
            return 0

        idxs = self.targets[name]
        if not isinstance(idxs, tuple):
            idxs = (idxs,)

        name = []
        for idx in idxs:
            if idx >= len(args):
                return 0

            arg = args[idx].obj_ea
            if not is_str_literal(arg):
                return 0

            name.append(get_str_literal(arg))

        if name:
            self.results.append('_'.join(name))
        return 0
Esempio n. 7
0
 def get_func_names():
     names = []
     for ea in idautils.Functions():
         name = ida_funcs.get_func_name(ea)
         if not name.startswith("sub_"):
             names.append(name)
     return names
Esempio n. 8
0
def make_name():
    callz = du.find_all_calls_to(f_name='log_info')
    for co in callz:

        # The *second* argument of ``GetProcAddress`` is the API name
        print("====")
        try:
            if co.args[2].type == 'string':
                api_name = co.args[2].val
            else:
                continue
        except:
            continue

        # double check :)
        # if not du.is_asg(co.node):
        #     continue

        if ' ' in api_name:
            continue
        if '\/' in api_name:
            continue

        new_name = "func_{}".format(api_name)
        func = idc.get_func_attr(co.ea, FUNCATTR_START)
        if 'sub_' not in ida_funcs.get_func_name(func):
            continue
        print("====")
        print(hex(func))
        print(new_name)
        idc.set_name(func, new_name, SN_CHECK)
Esempio n. 9
0
def main():
    """
    for each function in .text segment, we extract
    name, start_ea, end_ea, code, size attributes from IDA
    """
    results = {}

    start = time.time()
    funcs = get_funcs()

    text_segm = ida_segment.get_segm_by_name(".text")
    for func in funcs:
        # we only care about functions in .text segment
        if not in_range(text_segm, func.start_ea):
            continue

        name = ida_funcs.get_func_name(func.start_ea)
        code = ida_hexrays.decompile_func(func, None)
        results[name] = {   "name": name,
                            "start_ea": func.start_ea,
                            "end_ea": func.end_ea,
                            "code": code.__str__(),
                            "size": func.size()
                            }
    print("JSON:")
    print(json.dumps({"time": time.time() - start, "data": results}))
Esempio n. 10
0
def GetCanonicalName(f):
    n = ida_funcs.get_func_name(f)
    parts = n.split("_")
    if len(parts) == 3:
        return parts[1]
    else:
        return None
Esempio n. 11
0
def RenameMod(orig, new):
    i = ida_funcs.get_next_func(0)
    while (i != ida_idaapi.BADADDR):
        n = ida_funcs.get_func_name(i)
        if n.startswith(orig+"_"):
            RenameFuncWithNewMod(i,new)
        i = NextFunction(i)
Esempio n. 12
0
    def __repr__(self):
        try:
            func_name = get_func_name(self.func_t.start_ea)
        except:
            func_name = "<unknown>"

        return "<Func at 0x{:X}, name: {}>".format(self.func_t.start_ea, func_name)
Esempio n. 13
0
 def get_one_func_xref(self, func_name):
     for func_addr in idautils.Functions():
         func_name_t = ida_funcs.get_func_name(func_addr)
         if func_name == func_name_t:
             return self.get_func_xref(func_addr)
         else:
             continue
Esempio n. 14
0
 def getFunctionSymbols(self):
     function_symbols = {}
     function_offsets = self.getFunctions()
     for function_offset in function_offsets:
         function_name = ida_funcs.get_func_name(function_offset)
         if not re.match("sub_[0-9a-fA-F]+", function_name):
             function_symbols[function_offset] = function_name
     return function_symbols
Esempio n. 15
0
 def name(self):
     ea = self.address()
     try:
         flags = ida_bytes.get_full_flags(ea)
         if ida_bytes.has_name(flags):
             return ida_funcs.get_func_name(ea)
     except:
         pass
     return ""
def main():
    # Get current ea
    ea = ida_kernwin.get_screen_ea()
    if ea == ida_idaapi.BADADDR:
        print("Could not get get_screen_ea()")
        return

    seg = ida_segment.getseg(ea)
    if seg:
        # Loop from start to end in the current segment
        for funcea in idautils.Functions(seg.start_ea, seg.end_ea):
            print("Function %s at 0x%x" % (ida_funcs.get_func_name(funcea), funcea))

            # Find all code references to funcea
            for ref in idautils.CodeRefsTo(funcea, 1):
                print("  called from %s(0x%x)" % (ida_funcs.get_func_name(ref), ref))
    else:
        print("Please position the cursor within a segment")
Esempio n. 17
0
    def on_get_annotations(self, address, size, mouse_offs):
        annotations = []
        sp = get_sp_val()
        ip = get_ip_val()
        fi = FrameInfo()

        if sp and ip:
            arrow = sp if self.sp_arrow else None
            frame_start_ea = fi.ea
            funcname = get_func_name(ip)

            annotations.append((None, None, "", None))
            annotations.append((arrow, self.palette[4], "[Stack Pointer]", self.palette[1]))
            annotations.append((None, None, " address: 0x%x" % (sp), self.palette[3]))
            sp_boundaries = fi.get_element_boundaries(sp)
            if sp_boundaries and len(fi.members):
                start, end = sp_boundaries
                name, offs, msize, foffs = fi.members[start]
                annotations.append((None,  None, " points to: %s" % (name), self.palette[3]))

            annotations.append((None, None, "", None))
            annotations.append((None, None, "[Function]", self.palette[1]))
            annotations.append((None, None, " name: %s" % (funcname), self.palette[3]))
            annotations.append((None, None, " frame addr: 0x%x" % (frame_start_ea), self.palette[3]))

            if mouse_offs and len(fi.members):
                mouse_boundaries = fi.get_element_boundaries(address+mouse_offs)
                if mouse_boundaries:
                    start, end = mouse_boundaries
                    name, offs, msize, foffs = fi.members[start]
                    # "dist" is the distance from current variable to
                    # end of stack frame this is where a return address
                    # may be stored depending on the CPU architecture
                    dist = foffs-offs
                    
                    # address of frame member in memory
                    var_addr = frame_start_ea+offs

                    # add annotations
                    annotations.append((None, None, "", None))
                    annotations.append((None, None, "[Frame Member]", self.palette[1]))
                    annotations.append((None, None, " name: %s" % (name), self.palette[3]))
                    annotations.append((None, None, " addr: 0x%x" % (var_addr), self.palette[3]))
                    annotations.append((None, None, " offs: Frame+0x%x" % (offs), self.palette[3]))
                    annotations.append((None, None, " size: 0x%x" % (msize), self.palette[3]))
                    annotations.append((None, None, " distance: %s0x%x" % ("-" if dist < 0 else "",
                        abs(dist)), self.palette[3]))
                    annotations.append((None, None, " cursor: %s+0x%x" % (name,
                        address + mouse_offs - (frame_start_ea+offs)),
                        self.palette[3]))



        else:
            annotations.append((None, None, "Debugger inactive", self.palette[4]))

        return annotations
Esempio n. 18
0
def CompileFuncNamesFromRangeAsText(start,end,sep):
    x = start
    s = ""
    while (x<=end):
        n = ida_funcs.get_func_name(x)
        if (not n.startswith("sub_")):
            s += " " + sep + " " + n
        x = NextFunction(x)
    return s
Esempio n. 19
0
def RenameRangeWithAddr(start,end,s):
    x = start
    while (x<=end):
        n = ida_funcs.get_func_name(x)
        if (n.startswith("sub_")):
            RenameFuncWithAddr(x,s)
        else:
            NameCanonical(x,s,n)
        x = NextFunction(x)
Esempio n. 20
0
def PrefixRange(start, end, prefix) :
    x = start
    while x < end:
        n = ida_funcs.get_func_name(x)
        if n.startswith("sub_"):
            nn = prefix + n
            print "Renaming %s to %s\n" % (n, nn)
            ida_name.set_name(x,nn)
        x = NextFunction(x)
Esempio n. 21
0
def _function_name(ea):
    """Try to get the name of a function."""
    try:
        flags = ida_bytes.get_full_flags(ea)
        if ida_bytes.has_name(flags):
            return ida_funcs.get_func_name(ea)
    except:
        pass
    return "sub_{:x}".format(ea)
Esempio n. 22
0
    def get_tooltip(self, addr, mouse_offs):
        tooltip = '%X: ' % (addr + mouse_offs)

        if self.switch == 0:
            tooltip += '%s' % get_name(get_item_head(addr + mouse_offs))
        else:
            f = get_func(addr + mouse_offs)
            if f:
                tooltip += '%s' % get_func_name(f.startEA)
        return tooltip
Esempio n. 23
0
def color_blocks(fn, pc, size):
    fn_start = fn.start_ea
    fn_name = ida_funcs.get_func_name(fn_start)
    if ("COVERED_" not in fn_name):
        ida_name.set_name(fn_start, "COVERED_" + fn_name, ida_name.SN_CHECK)
    fn.color = FUNC_COLOR
    # PANDA blocks may be shorter than IDA blocks
    # so use the size to color just what PANDA executed
    i = 0
    while ((pc + i) < (pc + size)):
        ida_nalt.set_item_color(pc + i, INST_COLOR)
        i = i + 1
Esempio n. 24
0
 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) + "]"
Esempio n. 25
0
    def add_tmp_func(self, info_only=False):
        """
        添加临时sink函数
        info_only: 在添加函数信息的同时是否添加断点
        """

        input_str = ida_kernwin.ask_text(
            0, '',
            "请输入任意函数名/函数地址,及各参数类型(none, int, str),可输入多行\n例如:\nstrcmp str str")
        try:
            rules = [x.strip() for x in input_str.strip().split('\n')]
            for rule in rules:
                tgt_t = rule.split(' ')[0].strip()
                args_rule = [x.strip() for x in rule.split(' ')[1:]]

                if not tgt_t in self.tmp_func_dict:
                    if tgt_t.startswith('0x'):
                        addr_t = int(tgt_t, 16)
                        addr_hexstr = hexstr(addr_t)
                        CUSTOM_FUNC[addr_hexstr] = {'args_rule': args_rule}
                        self.tmp_func_dict[addr_hexstr] = [addr_t]
                        if info_only == False:
                            ida_dbg.add_bpt(addr_t, 0, idc.BPT_DEFAULT)
                    else:
                        for func_addr_t in idautils.Functions():
                            func_name_t = ida_funcs.get_func_name(func_addr_t)
                            if func_name_t == tgt_t:
                                CUSTOM_FUNC[func_name_t] = {
                                    'args_rule': args_rule
                                }
                                self.tmp_func_dict[func_name_t] = []
                                for xref_addr_t in idautils.CodeRefsTo(
                                        func_addr_t, 0):
                                    self.tmp_func_dict[func_name_t].append(
                                        xref_addr_t)
                                    if info_only == False:
                                        ida_dbg.add_bpt(
                                            xref_addr_t, 0, idc.BPT_DEFAULT)
                                    else:
                                        continue
                                break
                            else:
                                continue
                else:
                    CUSTOM_FUNC[tgt_t] = {'args_rule': args_rule}
                    for xref_addr_t in self.tmp_func_dict[tgt_t]:
                        if info_only == False:
                            ida_dbg.add_bpt(xref_addr_t, 0, idc.BPT_DEFAULT)
                        else:
                            continue
                FELogger.info("已添加断点:%s" % rule)
        except Exception as e:
            FELogger.info("输入信息有误:%s" % e)
Esempio n. 26
0
 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) + "]"
Esempio n. 27
0
    def _init_func_thunk_ctrl_flow(self):
        """Initializes the control flow redirections and targets
        using function thunks"""

        # We only support the ELF format for now
        inf = ida_idaapi.get_inf_structure()
        if inf.filetype != ida_ida.f_ELF:
            return

        # List the function thunks first
        input_file_path = ida_nalt.get_input_file_path()
        image_parser = create_elf_image_parser(input_file_path)
        function_thunk_list = image_parser.get_function_thunk_list()

        # Go through each function thunk, and look at its cross references; there
        # should always be only one user, which is the wrapper around the imported
        # function
        is_32_bit = image_parser.get_image_bitness() == 32

        for function_thunk in function_thunk_list:
            thunk_va = function_thunk.start

            redirection_dest = (ida_bytes.get_wide_dword(thunk_va) if is_32_bit
                                else ida_bytes.get_qword(thunk_va))

            caller_address = ida_xref.get_first_cref_to(redirection_dest)
            if caller_address == ida_idaapi.BADADDR:
                continue

            redirection_source = idc.get_func_attr(caller_address,
                                                   idc.FUNCATTR_START)
            caller_function_name = ida_funcs.get_func_name(redirection_source)

            if function_thunk.name in caller_function_name:
                print(
                    "anvill: Redirecting the user {:x} of thunk {} at rva {:x} to {:x}"
                    .format(
                        redirection_source,
                        function_thunk.name,
                        function_thunk.start,
                        redirection_dest,
                    ))

                self.add_control_flow_redirection(redirection_source,
                                                  redirection_dest)

            print(
                "anvill: Adding target list {:x} -> [{:x}, complete=True] for {}"
                .format(caller_address, redirection_dest, function_thunk.name))

            self.set_control_flow_targets(caller_address, [redirection_dest],
                                          True)
Esempio n. 28
0
 def getFunctionSymbols(self):
     function_symbols = {}
     function_offsets = self.getFunctions()
     for function_offset in function_offsets:
         function_name = ida_funcs.get_func_name(function_offset)
         # apply demangling if required
         if "@" in function_name:
             demangled = ida_name.demangle_name(function_name, 0)
             if demangled:
                 function_name = demangled
         if not re.match("sub_[0-9a-fA-F]+", function_name):
             function_symbols[function_offset] = function_name
     return function_symbols
Esempio n. 29
0
def is_func_call(ea):
    """
    判读是否是一个函数调用指令
    """

    op1 = idc.print_operand(ea, 0)
    for func_addr in idautils.Functions():
        func_name = ida_funcs.get_func_name(func_addr)
        if op1 == func_name:
            return True
        else:
            continue
    return False
Esempio n. 30
0
    def activate(self, ctx):
        user_input = ida_kernwin.ask_yn(
            ida_kernwin.ASKBTN_YES, "Would you like to export all functions?")
        if user_input == ida_kernwin.ASKBTN_CANCEL:
            return 1

        output_file_name_hint = ""

        p = anvill.get_program()

        if user_input == ida_kernwin.ASKBTN_NO:
            screen_cursor = ida_kernwin.get_screen_ea()
            function_name = ida_funcs.get_func_name(screen_cursor)
            if function_name is None:
                print("anvill: The cursor is not located inside a function")
                return 1

            output_file_name_hint = function_name + ".json"

            try:
                p.add_function_definition(screen_cursor)

            except:
                print(
                    "anvill: Failed to process the function at address {0:x}".
                    format(screen_cursor))
                return 1

        else:
            function_address_list = idautils.Functions()
            for function_address in function_address_list:
                try:
                    p.add_function_definition(function_address)

                except:
                    print(
                        "anvill: Failed to process the function at address {0:x}"
                        .format(function_address))

            output_file_name_hint = "program.json"

        output_path = ida_kernwin.ask_file(
            True, output_file_name_hint, "Select where to save the spec file")
        if not output_path:
            return 1

        output = json.dumps(p.proto(), sort_keys=False, indent=2)

        print("anvill: Saving the spec file to {}".format(output_path))
        with open(output_path, "w") as f:
            f.write(output)
Esempio n. 31
0
def show_graph():
    f = ida_funcs.get_func(ida_kernwin.get_screen_ea())
    if not f:
        print("Must be in a function")
        return
    # Iterate through all function instructions and take only call instructions
    result = []
    tmp = ida_ua.insn_t()
    for x in [
            x for x in idautils.FuncItems(f.start_ea)
            if (ida_ua.decode_insn(tmp, x) and ida_idp.is_call_insn(tmp))
    ]:
        for xref in idautils.XrefsFrom(x, ida_xref.XREF_FAR):
            if not xref.iscode: continue
            t = ida_funcs.get_func_name(xref.to)
            if not t:
                t = hex(xref.to)
            result.append(t)
    g = MyGraph(ida_funcs.get_func_name(f.start_ea), result)
    if g.Show():
        return g
    else:
        return None
Esempio n. 32
0
    def __process_functions(self):
        functions = list()

        start = ida_ida.cvar.inf.min_ea
        end = ida_ida.cvar.inf.max_ea

        # find first function head chunk in the range
        chunk = ida_funcs.get_fchunk(start)

        if not chunk:
            chunk = ida_funcs.get_next_fchunk(start)
        while chunk and chunk.start_ea < end and (chunk.flags
                                                  & ida_funcs.FUNC_TAIL) != 0:
            chunk = ida_funcs.get_next_fchunk(chunk.start_ea)

        func = chunk

        while func and func.start_ea < end:
            start_ea = func.start_ea

            func_flags = ida_bytes.get_full_flags(start_ea)
            func_name = ida_funcs.get_func_name(start_ea)
            func_name_demangled = ida_name.get_demangled_name(
                start_ea, 0xFFFF, 0, 0)
            func_autonamed = func_flags & ida_bytes.FF_LABL != 0
            func_public = ida_name.is_public_name(start_ea)

            function = {
                'start_rva': start_ea - self._base,
                'name': func_name,
                'name_demangled': func_name_demangled,
                'is_public': func_public,
                'is_autonamed': func_autonamed
            }

            # PE32/PE32+ only support binaries up to 2GB
            if function['start_rva'] >= 2**32:
                print('RVA out of range for function: ' + function['name'],
                      file=sys.stderr)

            self.__process_function_typeinfo(function, func)

            function['labels'] = self.__process_function_labels(func)

            functions.append(function)

            func = ida_funcs.get_next_func(start_ea)

        return functions
Esempio n. 33
0
def find_import_ref(dllname):
    imports = find_imported_funcs(dllname)
    R = dict()
    for i, (ea, name,_) in enumerate(imports):
        #print "%x -> %s" % (ea, name)
        for xref in idautils.XrefsTo(ea):
            # check if referrer is a thunk
            ea = xref.frm
            f = ida_funcs.get_func(ea)
            if f and (f.flags & ida_funcs.FUNC_THUNK) != 0:
                imports.append([f.start_ea, ida_funcs.get_func_name(f.start_ea), 0])
                #print "\t%x %s: from a thunk, parent added %x" % (ea, name, f.start_ea)
                continue

            # save results
            if i not in R:
                R[i] = []

            R[i].append(ea)

    return (imports, R)