Python idaapi.get_func() Examples

The following are 30 code examples of idaapi.get_func(). You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may also want to check out all available functions/classes of the module idaapi , or try the search function .
Example #1
Source File: win_driver_plugin.py    From win_driver_plugin with BSD 3-Clause "New" or "Revised" License 13 votes vote down vote up
def find_dispatch_by_struct_index():
    """Attempts to locate the dispatch function based off it being loaded in a structure
    at offset 70h, based off of https://github.com/kbandla/ImmunityDebugger/blob/master/1.73/Libs/driverlib.py """
    
    out = set()
    for function_ea in idautils.Functions():
        flags = idc.get_func_flags(function_ea)
        # skip library functions
        if flags & idc.FUNC_LIB:
            continue
        func = idaapi.get_func(function_ea)
        addr = func.startEA
        while addr < func.endEA:
            if idc.GetMnem(addr) == 'mov':
                if '+70h' in idc.GetOpnd(addr, 0) and idc.GetOpType(addr, 1) == 5:
                    out.add(idc.GetOpnd(addr, 1))
            addr = idc.NextHead(addr)
    return out 
Example #2
Source File: win_driver_plugin.py    From win_driver_plugin with BSD 3-Clause "New" or "Revised" License 7 votes vote down vote up
def find_all_ioctls():
    """
    From the currently selected address attempts to traverse all blocks inside the current function to find all immediate values which
    are used for a comparison/sub immediately before a jz. Returns a list of address, second operand pairs.
    """
    
    ioctls = []
    # Find the currently selected function and get a list of all of it's basic blocks
    addr = idc.ScreenEA()
    f = idaapi.get_func(addr)
    fc = idaapi.FlowChart(f, flags=idaapi.FC_PREDS)
    for block in fc:
        # grab the last two instructions in the block 
        last_inst = idc.PrevHead(block.endEA)
        penultimate_inst = idc.PrevHead(last_inst)
        # If the penultimate instruction is cmp or sub against an immediate value immediately preceding a 'jz' 
        # then it's a decent guess that it's an IOCTL code (if this is a dispatch function)
        if idc.GetMnem(penultimate_inst) in ['cmp', 'sub'] and idc.GetOpType(penultimate_inst, 1) == 5:
            if idc.GetMnem(last_inst) == 'jz':
                value = get_operand_value(penultimate_inst)
                ioctls.append((penultimate_inst, value))
                ioctl_tracker.add_ioctl(penultimate_inst, value)
    return ioctls 
Example #3
Source File: misc.py    From heap-viewer with GNU General Public License v3.0 6 votes vote down vote up
def get_libc_version_disasm():
    fnc_addr = get_name_ea_simple("gnu_get_libc_version")
    if fnc_addr == BADADDR:
        return None

    add_func(fnc_addr)
    fnc = get_func(fnc_addr)
    if fnc is None:
        return None

    for head in Heads(fnc.start_ea, fnc.end_ea):
        disas = GetDisasm(head)
        if disas.startswith("lea"):
            m = re.search(";\s\"(.*)\"$", disas)
            if m:
                return m.groups()[0]
    return None

# -------------------------------------------------------------------------- 
Example #4
Source File: core.py    From Sark with MIT License 6 votes vote down vote up
def get_func(func_ea):
    """get_func(func_t or ea) -> func_t

    Take an IDA function (``idaapi.func_t``) or an address (EA) and return
    an IDA function object.

    Use this when APIs can take either a function or an address.

    Args:
        func_ea: ``idaapi.func_t`` or ea of the function.

    Returns:
        An ``idaapi.func_t`` object for the given address. If a ``func_t`` is
        provided, it is returned.
    """
    if isinstance(func_ea, idaapi.func_t):
        return func_ea
    func = idaapi.get_func(func_ea)
    if func is None:
        raise exceptions.SarkNoFunction("No function at 0x{:08X}".format(func_ea))

    return func 
Example #5
Source File: codeblock.py    From Sark with MIT License 6 votes vote down vote up
def get_nx_graph(ea, ignore_external=False):
    """Convert an IDA flowchart to a NetworkX graph."""
    nx_graph = networkx.DiGraph()
    func = idaapi.get_func(ea)
    flowchart = FlowChart(func, ignore_external=ignore_external)
    for block in flowchart:
        # Make sure all nodes are added (including edge-less nodes)
        nx_graph.add_node(block.start_ea)

        for pred in block.preds():
            nx_graph.add_edge(pred.start_ea, block.start_ea)
        for succ in block.succs():
            nx_graph.add_edge(block.start_ea, succ.start_ea)

    return nx_graph 
Example #6
Source File: idautils.py    From dumpDex with Apache License 2.0 6 votes vote down vote up
def FuncItems(start):
    """
    Get a list of function items

    @param start: address of the function

    @return: ea of each item in the function
    """
    func = idaapi.get_func(start)
    if not func:
        return
    fii = idaapi.func_item_iterator_t()
    ok = fii.set(func)
    while ok:
        yield fii.current()
        ok = fii.next_code() 
Example #7
Source File: interesting_xor.py    From idataco with GNU General Public License v3.0 6 votes vote down vote up
def find_interesting_xors(self):
        next_xor = idc.FindText(idc.MinEA(), idc.SEARCH_DOWN|idc.SEARCH_NEXT, 0, 0, "xor")
        while next_xor != idc.BADADDR:
            if idc.GetOpnd(next_xor, 0) != idc.GetOpnd(next_xor, 1):
                entry = {"func":"", "addr": next_xor, "loop":False, "disasm": idc.GetDisasm(next_xor)}
                func = idaapi.get_func(next_xor)
                if func:
                    entry["func"] = idaapi.get_name(idc.BADADDR, func.startEA)
                    heads = idautils.Heads(next_xor, func.endEA)
                    lxors = []
                    for head in heads:
                        if idc.GetMnem(head).startswith('j'):
                            jmp_addr = idc.GetOperandValue(head,0)
                            if jmp_addr < next_xor and jmp_addr > func.startEA:
                                entry["loop"] = True
                                break
                self._interesting_xors.append(entry)
            next_xor = idc.FindText(idc.NextHead(next_xor), idc.SEARCH_DOWN|idc.SEARCH_NEXT, 0, 0, "xor") 
Example #8
Source File: hint_calls.py    From idawilli with Apache License 2.0 6 votes vote down vote up
def enum_function_addrs(fva):
    '''
    yield the effective addresses of each instruction in the given function.
    these addresses are not guaranteed to be in any order.
    
    Args:
      fva (int): the starting address of a function
    
    Returns:
      sequence[int]: the addresses of each instruction
    '''
    f = idaapi.get_func(fva)
    if not f:
        raise ValueError('not a function')

    for block in idaapi.FlowChart(f):
        ea = block.startEA
        while ea <= block.endEA:
            yield ea
            ea = idc.NextHead(ea) 
Example #9
Source File: ida_api.py    From Karta with MIT License 6 votes vote down vote up
def funcAt(self, ea):
        """Return the function that includes the given address.

        Args:
            ea (int): effective address of the wanted function

        Return Value:
            A function instance, or None if no such function
        """
        func = idaapi.get_func(ea)
        if func is None:
            return None
        # can now use sark more freely
        try:
            return sark.Function(ea)
        except sark.exceptions.SarkNoFunction:
            # just to be sure
            return None

    # Overridden base function 
Example #10
Source File: IDAMagicStrings.py    From idamagicstrings with GNU Affero General Public License v3.0 6 votes vote down vote up
def OnDblClick(self, node_id):
    eas = self.nodes_ea[node_id]
    if len(eas) == 1:
      jumpto(list(eas)[0])
    else:
      items = []
      for ea in eas:
        func = idaapi.get_func(ea)
        if func is None:
          s = get_strlit_contents(ea)
          s = s.decode("utf-8")
          if s is not None and s.find(str(self[node_id])) == -1:
            s = get_strlit_contents(ea, strtype=1)
          else:
            s = GetDisasm(ea)
        else:
          s = get_func_name(func.start_ea)

        items.append(["0x%08x" % ea, repr(s)])

      chooser = CClassXRefsChooser("XRefs to %s" % str(self[node_id]), items)
      idx = chooser.Show(1)
      if idx > -1:
        jumpto(list(eas)[idx]) 
Example #11
Source File: hooks.py    From ida-minsc with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
def extra_cmt_changed(ea, line_idx, cmt):
    # FIXME: persist state for extra_cmts in order to determine what the original
    #        value was before modification. IDA doesn't seem to have an
    #        extra_cmt_changing event and instead calls this hook twice for every
    #        insertion.
    # XXX: this function is now busted in later versions of IDA because for some
    #      reason, Ilfak, is now updating the extra comment prior to dispatching
    #      this event. unfortunately, our tag cache doesn't allow us to identify
    #      the actual number of tags that are at an address, so there's no way
    #      to identify the actual change to the extra comment that the user made,
    #      which totally fucks up the refcount. in the current implementation, if
    #      we can't distinguish between the old and new extra comments, then its
    #      simply a no-op. this is okay for now...

    oldcmt = internal.netnode.sup.get(ea, line_idx)
    if oldcmt is not None: oldcmt = oldcmt.rstrip('\x00')
    ctx = internal.comment.contents if idaapi.get_func(ea) else internal.comment.globals

    MAX_ITEM_LINES = (idaapi.E_NEXT-idaapi.E_PREV) if idaapi.E_NEXT > idaapi.E_PREV else idaapi.E_PREV-idaapi.E_NEXT
    prefix = (idaapi.E_PREV, idaapi.E_PREV+MAX_ITEM_LINES, '__extra_prefix__')
    suffix = (idaapi.E_NEXT, idaapi.E_NEXT+MAX_ITEM_LINES, '__extra_suffix__')

    for l, r, key in (prefix, suffix):
        if l <= line_idx < r:
            if oldcmt is None and cmt is not None: ctx.inc(ea, key)
            elif oldcmt is not None and cmt is None: ctx.dec(ea, key)
            logging.debug(u"{:s}.extra_cmt_changed({:#x}, {:d}, {!s}, oldcmt={!s}) : {:s} refcount at address for tag {!s}.".format(__name__, ea, line_idx, utils.string.repr(cmt), utils.string.repr(oldcmt), 'Increasing' if oldcmt is None and cmt is not None else 'Decreasing' if oldcmt is not None and cmt is None else 'Doing nothing to', utils.string.repr(key)))
        continue
    return

### function scope 
Example #12
Source File: hooks.py    From ida-minsc with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
def old_changed(cls, ea, repeatable_cmt):
        if not cls.is_ready():
            return logging.debug(u"{:s}.old_changed({:#x}, {:d}) : Ignoring comment.changed event (database not ready) for a {:s} comment at {:#x}.".format('.'.join((__name__, cls.__name__)), ea, repeatable, 'repeatable' if repeatable else 'non-repeatable', ea))

        # first we'll grab our comment that the user updated
        logging.debug(u"{:s}.old_changed({:#x}, {:d}) : Received comment.changed event for a {:s} comment at {:#x}.".format('.'.join((__name__, cls.__name__)), ea, repeatable, 'repeatable' if repeatable else 'non-repeatable', ea))
        cmt = utils.string.of(idaapi.get_cmt(ea, repeatable_cmt))
        fn = idaapi.get_func(ea)

        # if we're in a function, then clear our contents.
        if fn:
            internal.comment.contents.set_address(ea, 0)

        # otherwise, just clear the tags globally
        else:
            internal.comment.globals.set_address(ea, 0)

        # simply grab the comment and update its refs
        res = internal.comment.decode(cmt)
        if res:
            cls._create_refs(ea, res)

        # otherwise, there's nothing to do if its empty
        else:
            return

        # and then re-write it back to its address, but not before disabling
        # our hooks that brought is here so that we can avoid any re-entrancy issues.
        ui.hook.idb.disable('cmt_changed')
        try:
            idaapi.set_cmt(ea, utils.string.to(internal.comment.encode(res)), repeatable_cmt)

        # now we can "finally" re-enable our hook
        finally:
            ui.hook.idb.enable('cmt_changed')

        # and then leave because hopefully things were updated properly
        return 
Example #13
Source File: ironstrings.py    From flare-ida with Apache License 2.0 5 votes vote down vote up
def get_bb_ends(address):
    """
    Get end addresses of all bbs in function containing address.
    :param address: address in function
    :return: list of bb end addresses
    """
    function = idaapi.get_func(address)
    flowchart = idaapi.FlowChart(function)
    return [idc.prev_head(bb.end_ea) for bb in flowchart] 
Example #14
Source File: shellcode_hash_search.py    From flare-ida with Apache License 2.0 5 votes vote down vote up
def markupLine(self, loc, sym, useDecompiler = False):
        comm = '%s!%s' % (sym.libName, sym.symbolName)
        logger.debug("Making comment @ 0x%08x: %s", loc, comm)
        if using_ida7api:
            idc.set_cmt(loc, str(comm), False)
            if useDecompiler and idaapi.get_func(loc) != None:
                self.addDecompilerComment(loc, str(comm))
        else:
            idc.MakeComm(loc, str(comm)) 
Example #15
Source File: function.py    From ida-minsc with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
def within(ea):
    '''Return true if the address `ea` is within a function.'''
    ea = interface.address.within(ea)
    return idaapi.get_func(ea) is not None and idaapi.segtype(ea) != idaapi.SEG_XTRN

# Checks if ea is contained in function or in any of its chunks 
Example #16
Source File: hooks.py    From ida-minsc with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
def rename(ea, newname):
    """This hook is when a user adds a name or removes it from the database.

    We simply increase the refcount for the "__name__" key, or decrease it
    if the name is being removed.
    """
    fl = database.type.flags(ea)
    labelQ, customQ = (fl & n == n for n in {idaapi.FF_LABL, idaapi.FF_NAME})
    #r, fn = database.xref.up(ea), idaapi.get_func(ea)
    fn = idaapi.get_func(ea)

    # figure out whether a global or function name is being changed, otherwise it's the function's contents
    ctx = internal.comment.globals if not fn or (interface.range.start(fn) == ea) else internal.comment.contents

    # if a name is being removed
    if not newname:
        # if it's a custom name
        if (not labelQ and customQ):
            ctx.dec(ea, '__name__')
            logging.debug(u"{:s}.rename({:#x}, {!s}) : Decreasing refcount for tag {!r} at address due to an empty name.".format(__name__, ea, utils.string.repr(newname), '__name__'))
        return

    # if it's currently a label or is unnamed
    if (labelQ and not customQ) or all(not q for q in {labelQ, customQ}):
        ctx.inc(ea, '__name__')
        logging.debug(u"{:s}.rename({:#x}, {!s}) : Increasing refcount for tag {!r} at address due to a new name.".format(__name__, ea, utils.string.repr(newname), '__name__'))
    return 
Example #17
Source File: hooks.py    From ida-minsc with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
def old_changed(cls, cb, a, cmt, repeatable):
        if not cls.is_ready():
            return logging.debug(u"{:s}.old_changed({!s}, {:#x}, {!s}, {:d}) : Ignoring comment.changed event (database not ready) for a {:s} comment at {:#x}.".format('.'.join((__name__, cls.__name__)), utils.string.repr(cb), interface.range.start(a), utils.string.repr(cmt), repeatable, 'repeatable' if repeatable else 'non-repeatable', interface.range.start(a)))

        # first thing to do is to identify whether we're in a function or not,
        # so we first grab the address from the area_t...
        logging.debug(u"{:s}.old_changed({!s}, {:#x}, {!s}, {:d}) : Received comment.changed event for a {:s} comment at {:#x}.".format('.'.join((__name__, cls.__name__)), utils.string.repr(cb), interface.range.start(a), utils.string.repr(cmt), repeatable, 'repeatable' if repeatable else 'non-repeatable', interface.range.start(a)))
        ea = interface.range.start(a)

        # then we can use it to verify that we're in a function. if not, then
        # this is a false alarm and we can leave.
        fn = idaapi.get_func(ea)
        if fn is None:
            return

        # we're using an old version of ida here, so start out empty
        internal.comment.globals.set_address(ea, 0)

        # grab our comment here and re-create its refs
        res = internal.comment.decode(utils.string.of(cmt))
        if res:
            cls._create_refs(fn, res)

        # if it's empty, then there's nothing to do and we can leave
        else:
            return

        # now we can simply re-write it it, but not before disabling our hooks
        # that got us here, so that we can avoid any re-entrancy issues.
        ui.hook.idb.disable('area_cmt_changed')
        try:
            idaapi.set_func_cmt(fn, utils.string.to(internal.comment.encode(res)), repeatable)

        # now we can "finally" re-enable our hook
        finally:
            ui.hook.idb.enable('area_cmt_changed')

        # that should've been it, so we can now just leave
        return

### database scope 
Example #18
Source File: hooks.py    From ida-minsc with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
def changed(cls, cb, a, cmt, repeatable):
        if not cls.is_ready():
            return logging.debug(u"{:s}.changed({!s}, {:#x}, {!s}, {:d}) : Ignoring comment.changed event (database not ready) for a {:s} comment at {:#x}.".format('.'.join((__name__, cls.__name__)), utils.string.repr(cb), interface.range.start(a), utils.string.repr(cmt), repeatable, 'repeatable' if repeatable else 'non-repeatable', interface.range.start(a)))

        # First we'll check to see if this is an actual function comment by confirming
        # that we're in a function, and that our comment is not empty.
        logging.debug(u"{:s}.changed({!s}, {:#x}, {!s}, {:d}) : Received comment.changed event for a {:s} comment at {:#x}.".format('.'.join((__name__, cls.__name__)), utils.string.repr(cb), interface.range.start(a), utils.string.repr(cmt), repeatable, 'repeatable' if repeatable else 'non-repeatable', interface.range.start(a)))
        fn = idaapi.get_func(interface.range.start(a))
        if fn is None and not cmt:
            return

        # Grab our new comment, because we're going to submit this later to a coro
        newcmt = utils.string.of(idaapi.get_func_cmt(fn, repeatable))

        # We need to disable our hooks so that we can prevent re-entrancy issues
        hooks = ['changing_area_cmt', 'area_cmt_changed'] if idaapi.__version__ < 7.0 else ['changing_range_cmt', 'range_cmt_changed']
        [ ui.hook.idb.disable(event) for event in hooks ]

        # Now we can use our coroutine to update the comment state, so that the
        # coroutine will perform the final update.
        try:
            cls.event.send((interface.range.start(fn), bool(repeatable), None))

        # If a StopIteration was raised when submitting the comment to the
        # coroutine, then we somehow desynchronized. Re-initialize the coroutine
        # with the hope that things are fixed.
        except StopIteration, E:
            logging.fatal(u"{:s}.changed({!s}, {:#x}, {!s}, {:d}) : Unexpected termination of event handler. Re-instantiating it.".format('.'.join((__name__, cls.__name__)), utils.string.repr(cb), interface.range.start(a), utils.string.repr(cmt), repeatable))
            cls.event = cls._event(); next(cls.event)

        # Last thing to do is to re-enable the hooks that we disabled 
Example #19
Source File: hooks.py    From ida-minsc with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
def changing(cls, cb, a, cmt, repeatable):
        if not cls.is_ready():
            return logging.debug(u"{:s}.changing({!s}, {:#x}, {!s}, {:d}) : Ignoring comment.changing event (database not ready) for a {:s} comment at {:#x}.".format('.'.join((__name__, cls.__name__)), utils.string.repr(cb), interface.range.start(a), utils.string.repr(cmt), repeatable, 'repeatable' if repeatable else 'non-repeatable', interface.range.start(a)))

        # First we'll check to see if this is an actual function comment by confirming
        # that we're in a function, and that our comment is not empty.
        logging.debug(u"{:s}.changing({!s}, {:#x}, {!s}, {:d}) : Received comment.changing event for a {:s} comment at {:#x}.".format('.'.join((__name__, cls.__name__)), utils.string.repr(cb), interface.range.start(a), utils.string.repr(cmt), repeatable, 'repeatable' if repeatable else 'non-repeatable', interface.range.start(a)))
        fn = idaapi.get_func(interface.range.start(a))
        if fn is None and not cmt:
            return

        # Grab our old comment, because we're going to submit this later to a coro
        oldcmt = utils.string.of(idaapi.get_func_cmt(fn, repeatable))

        # We need to disable our hooks so that we can prevent re-entrancy issues
        hooks = ['changing_area_cmt', 'area_cmt_changed'] if idaapi.__version__ < 7.0 else ['changing_range_cmt', 'range_cmt_changed']
        [ ui.hook.idb.disable(event) for event in hooks ]

        # Now we can use our coroutine to begin the comment update, so that
        # later, the "changed" event can do the actual update.
        try:
            cls.event.send((interface.range.start(fn), bool(repeatable), utils.string.of(cmt)))

        # If a StopIteration was raised when submitting the comment to the
        # coroutine, then we somehow desynchronized. Re-initialize the coroutine
        # with the hope that things are fixed.
        except StopIteration, E:
            logging.fatal(u"{:s}.changing({!s}, {:#x}, {!s}, {:d}) : Unexpected termination of event handler. Re-instantiating it.".format('.'.join((__name__, cls.__name__)), utils.string.repr(cb), interface.range.start(a), utils.string.repr(cmt), repeatable))
            cls.event = cls._event(); next(cls.event)

        # Last thing to do is to re-enable the hooks that we disabled 
Example #20
Source File: _comment.py    From ida-minsc with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
def _key(cls, ea):
        '''Converts the address `ea` to a key that's used to store contents data for the specified function.'''
        res = idaapi.get_func(ea)
        return internal.interface.range.start(res) if res else None 
Example #21
Source File: hexrays.py    From bap-ida-python with MIT License 5 votes vote down vote up
def find_cfunc(ea):
    """Get cfuncptr_t from EA."""
    func = idaapi.get_func(ea)
    if func:
        return idaapi.decompile(func) 
Example #22
Source File: ida.py    From bap-ida-python with MIT License 5 votes vote down vote up
def output_symbols(out):
    """Dump symbols."""
    try:
        from idaapi import get_func_name2 as get_func_name
        # Since get_func_name is deprecated (at least from IDA 6.9)
    except ImportError:
        from idaapi import get_func_name
        # Older versions of IDA don't have get_func_name2
        # so we just use the older name get_func_name

    def func_name_propagate_thunk(ea):
        current_name = get_func_name(ea)
        if current_name[0].isalpha():
            return current_name
        func = idaapi.get_func(ea)
        temp_ptr = idaapi.ea_pointer()
        ea_new = idaapi.BADADDR
        if func.flags & idaapi.FUNC_THUNK == idaapi.FUNC_THUNK:
            ea_new = idaapi.calc_thunk_func_target(func, temp_ptr.cast())
        if ea_new != idaapi.BADADDR:
            ea = ea_new
        propagated_name = get_func_name(ea) or ''  # Ensure it is not `None`
        if len(current_name) > len(propagated_name) > 0:
            return propagated_name
        else:
            return current_name
            # Fallback to non-propagated name for weird times that IDA gives
            #     a 0 length name, or finds a longer import name

    for ea in idautils.Segments():
        fs = idautils.Functions(idc.SegStart(ea), idc.SegEnd(ea))
        for f in fs:
            out.write('("%s" 0x%x 0x%x)\n' % (
                func_name_propagate_thunk(f),
                idc.GetFunctionAttr(f, idc.FUNCATTR_START),
                idc.GetFunctionAttr(f, idc.FUNCATTR_END))) 
Example #23
Source File: ida_batch_decompile.py    From ida-batch_decompile with GNU General Public License v3.0 5 votes vote down vote up
def __init__(self, location):
        self.at = location
        # self.name = GetFunctionName(location)
        self.name = GetFuncOffset(location)
        self.start = 0
        self.end = 0
        self.func_offset = 0
        try:
            _func = idaapi.get_func(location)
            self.start = _func.startEA
            self.end = _func.endEA  # ==FindFuncEnd(location)
            self.func_offset = self.start - self.at
        except Exception, e:
            logger.exception(e) 
Example #24
Source File: data_flow.py    From ida_kernelcache with MIT License 5 votes vote down vote up
def _create_flow(function, bounds):
    """Create a FlowChart."""
    f, b = None, None
    if function is not None:
        f = idaapi.get_func(function)
        if f is None:
            _log(0, 'Bad func {:#x}', func)
            return None
    if bounds is not None:
        b = (start, end)
    return idaapi.FlowChart(f=f, bounds=b) 
Example #25
Source File: ida_prefix.py    From prefix with MIT License 5 votes vote down vote up
def graph_down(ea, path=set()):
    """
    Recursively collect all function calls.

    Copied with minor modifications from
    http://hooked-on-mnemonics.blogspot.com/2012/07/renaming-subroutine-blocks-and.html
    """
    path.add(ea)

    #
    # extract all the call instructions from the current function
    #

    call_instructions = []
    instruction_info = idaapi.insn_t()
    for address in idautils.FuncItems(ea):

        # decode the instruction
        if not idaapi.decode_insn(instruction_info, address):
            continue

        # check if this instruction is a call
        if not idaapi.is_call_insn(instruction_info):
            continue

        # save this address as a call instruction
        call_instructions.append(address)

    #
    # iterate through all the instructions in the target function (ea) and
    # inspect all the call instructions
    #

    for x in call_instructions:

        #  TODO
        for r in idautils.XrefsFrom(x, idaapi.XREF_FAR):
            #print(0x%08X" % h, "--calls-->", "0x%08X" % r.to)
            if not r.iscode:
                continue

            # get the function pointed at by this call
            func = idaapi.get_func(r.to)
            if not func:
                continue

            # ignore calls to imports / library calls / thunks
            if (func.flags & (idaapi.FUNC_THUNK | idaapi.FUNC_LIB)) != 0:
                continue

            #
            # if we have not traversed to the destination function that this
            # call references, recurse down to it to continue our traversal
            #

            if r.to not in path:
                graph_down(r.to, path)

    return path 
Example #26
Source File: golang_loader_assist.py    From golang_loader_assist with GNU General Public License v3.0 5 votes vote down vote up
def find_func_by_name(name):
    text_seg = get_text_seg()
    if text_seg is None:
        return None

    for addr in Functions(text_seg.start_ea, text_seg.end_ea):
        if name == idaapi.get_func_name(addr):
            return idaapi.get_func(addr)

    return None 
Example #27
Source File: golang_loader_assist.py    From golang_loader_assist with GNU General Public License v3.0 5 votes vote down vote up
def traverse_xrefs(func):
    func_created = 0

    if func is None:
        return func_created

    # First
    func_xref = idaapi.get_first_cref_to(func.start_ea)
    # Attempt to go through crefs
    while func_xref != BADADDR:
        # See if there is a function already here
        if idaapi.get_func(func_xref) is None:
            # Ensure instruction bit looks like a jump
            func_end = ida_search.find_code(func_xref, SEARCH_DOWN)
            if idc.print_insn_mnem(func_end) == "jmp":
                # Ensure we're jumping back "up"
                func_start = idc.get_operand_value(func_end, 0)
                if func_start < func_xref:
                    if ida_funcs.add_func(func_start, func_end):
                        func_created += 1
                    else:
                        # If this fails, we should add it to a list of failed functions
                        # Then create small "wrapper" functions and backtrack through the xrefs of this
                        error('Error trying to create a function @ 0x%x - 0x%x' %(func_start, func_end))
        else:
            xref_func = idaapi.get_func(func_xref)
            # Simple wrapper is often runtime_morestack_noctxt, sometimes it isn't though...
            if is_simple_wrapper(xref_func.start_ea):
                debug('Stepping into a simple wrapper')
                func_created += traverse_xrefs(xref_func)
            if idaapi.get_func_name(xref_func.start_ea) is not None and 'sub_' not in idaapi.get_func_name(xref_func.start_ea):
                debug('Function @0x%x already has a name of %s; skipping...' % (func_xref, idaapi.get_func_name(xref_func.start_ea)))
            else:
                debug('Function @ 0x%x already has a name %s' % (xref_func.start_ea, idaapi.get_func_name(xref_func.start_ea)))

        func_xref = idaapi.get_next_cref_to(func.start_ea, func_xref)

    return func_created 
Example #28
Source File: golang_loader_assist.py    From golang_loader_assist with GNU General Public License v3.0 5 votes vote down vote up
def create_runtime_ms():
    debug('Attempting to find runtime_morestack function for hooking on...')

    text_seg = get_text_seg()
    if text_seg is None:
        debug('Failed to get text segment')
        return None

    #   Opcodes for "mov     large dword ptr ds:1003h, 0", binary search is faster than text search
    opcodes = 'c7 05 03 10 00 00 00 00 00 00'
    if idaapi.get_inf_structure().is_64bit():
        #   Opcodes for "mov     qword ptr ds:dword_1000+3, 0"
        opcodes = '48 c7 04 25 03 10 00 00 00 00 00 00'

    runtime_ms_end = idaapi.find_binary(text_seg.start_ea, text_seg.end_ea, opcodes, 0, SEARCH_DOWN)
    if runtime_ms_end == BADADDR:
        debug('Failed to find opcodes associated with runtime_morestack: %s' % opcodes)
        return None

    runtime_ms = idaapi.get_func(runtime_ms_end)
    if runtime_ms is None:
        debug('Failed to get runtime_morestack function from address @ 0x%x' % runtime_ms_end)
        return None

    if idc.set_name(runtime_ms.start_ea, "runtime_morestack", SN_PUBLIC):
        debug('Successfully found runtime_morestack')
    else:
        debug('Failed to rename function @ 0x%x to runtime_morestack' % runtime_ms.start_ea)

    return runtime_ms 
Example #29
Source File: codeblock.py    From Sark with MIT License 5 votes vote down vote up
def __init__(self, f=None, bounds=None, flags=idaapi.FC_PREDS, ignore_external=False):
        if f is None and bounds is None:
            f = idaapi.get_screen_ea()
        if f is not None:
            f = get_func(f)
        if ignore_external:
            flags |= idaapi.FC_NOEXT

        super(FlowChart, self).__init__(f=f, bounds=bounds, flags=flags) 
Example #30
Source File: core.py    From Sark with MIT License 5 votes vote down vote up
def is_function(ea):
    try:
        get_func(ea)
        return True
    except exceptions.SarkNoFunction:
        return False