Python idaapi 模块,FlowChart() 实例源码

我们从Python开源项目中,提取了以下28个代码示例,用于说明如何使用idaapi.FlowChart()

项目:idawilli    作者:williballenthin    | 项目源码 | 文件源码
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)
项目:win_driver_plugin    作者:mwrlabs    | 项目源码 | 文件源码
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 immediatly preceding a 'jz' 
        # then it's a decent guess that it's an IOCTL code (if this is a disptach function)
        if idc.GetMnem(penultimate_inst) in ['cmp', 'sub'] and idc.GetOpType(penultimate_inst, 1) == 5:
            if idc.GetMnem(last_inst) == 'jz':
                ioctl_tracker.add_ioctl(penultimate_inst)
    for inst in ioctl_tracker.ioctl_locs:
        value = get_operand_value(inst)
        ioctls.append((inst, value))
    return ioctls
项目:bingrep    作者:hada2    | 项目源码 | 文件源码
def get_cfg(function_start, function_end):
    f_name = GetFunctionName(function_start)

    cfg = idaapi.FlowChart(idaapi.get_func(function_start))

    return list(cfg)
项目:idapython    作者:mr-tz    | 项目源码 | 文件源码
def find_tight_loops(fva):
    """ Code from Willi Ballenthin """
    tight_loops = []
    function = idaapi.get_func(fva)
    for bb in idaapi.FlowChart(function):
        # bb.endEA is the first addr not in the basic block
        bb_end = idc.PrevHead(bb.endEA)
        for x in idautils.XrefsFrom(bb_end):
            if x.to == bb.startEA and bb.startEA < bb_end:
                tight_loops.append((bb.startEA, bb_end))
    if tight_loops:
        g_logger.debug("Tight loops in 0x%x: %s", fva, ["0x%x - 0x%x" % (s, e) for (s, e) in tight_loops])
    return tight_loops
项目:ropf    作者:kevinkoo001    | 项目源码 | 文件源码
def _get_blocks_codes_per_func_iter():
    """
    Iterative function to generate all blocks and opcodes
    :return: N/A
    """
    all_blocks = {}
    all_codes = {}
    all_opcodes = []
    for func in idautils.Functions():
        # blocks_in_func contains
        #   <idaapi.BasicBlock object at 0x0545F3F0>, ...
        blocks_in_func = idaapi.FlowChart(idaapi.get_func(func))
        blocks = []
        for block in blocks_in_func:

            # IDA BUG! block.startEA == block.endEA??
            # Should be in the range "block.startEA <= block < block.endEA"
            if block.startEA != block.endEA:
                blocks.append((block.startEA, block.endEA))
            for head in idautils.Heads(block.startEA, block.endEA):
                ibytes = idc.GetManyBytes(head, idc.ItemEnd(head) - head)
                spd = idc.GetSpd(head)
                all_codes[head] = insn.Instruction(head, ibytes, spd)

                # IDA BUG! all_codes[head].bytes == 0??
                # The size of the code should be positive
                if all_codes[head].bytes != 0:
                    all_opcodes.append((all_codes[head].addr, all_codes[head].addr + len(all_codes[head].bytes)))
        all_blocks[func] = blocks
    yield (all_blocks, all_opcodes)
项目:idawilli    作者:williballenthin    | 项目源码 | 文件源码
def get_basic_blocks(fva):
    '''
    return sequence of `BasicBlock` instances for given function.
    '''
    ret = []
    func = idaapi.get_func(fva)
    if func is None:
        return ret

    for bb in idaapi.FlowChart(func):
        ret.append(BasicBlock(va=bb.startEA,
                              size=bb.endEA - bb.startEA))

    return ret
项目:idascripts    作者:ctfhacker    | 项目源码 | 文件源码
def color_block(ea=None, color=0x55ff7f):
    """http://reverseengineering.stackexchange.com/questions/10662/change-block-node-color-with-idapython
    and WanderingGlitch for the tip of refresh_idaview_anyway()"""

    func_top = fn.top()

    f = idaapi.get_func(ea)
    g = idaapi.FlowChart(f, flags=idaapi.FC_PREDS)
    bb_id = get_bb_id(g, ea)

    p = idaapi.node_info_t()
    p.bg_color = color

    idaapi.set_node_info2(func_top, bb_id, p, idaapi.NIF_BG_COLOR | idaapi.NIF_FRAME_COLOR)
    idaapi.refresh_idaview_anyway()
项目:idascripts    作者:ctfhacker    | 项目源码 | 文件源码
def bottom(func):
    '''Return the exit-points of the function ``func``.'''
    fn = by(func)
    fc = idaapi.FlowChart(f=fn, flags=idaapi.FC_PREDS)
    exit_types = (fc_block_type_t.fcb_ret,fc_block_type_t.fcb_cndret,fc_block_type_t.fcb_noret,fc_block_type_t.fcb_enoret,fc_block_type_t.fcb_error)
    return tuple(database.address.prev(n.endEA) for n in fc if n.type in exit_types)
项目:idascripts    作者:ctfhacker    | 项目源码 | 文件源码
def iterate(cls, func):
        '''Returns each idaapi.BasicBlock for the function ``func``.'''
        fn = by(func)
        fc = idaapi.FlowChart(f=fn, flags=idaapi.FC_PREDS)
        for bb in fc:
            yield bb
        return
项目:idascripts    作者:ctfhacker    | 项目源码 | 文件源码
def flow(func):
    '''Return a flow chart object for the function ``func``.'''
    fn = by(func)
    fc = idaapi.FlowChart(f=fn, flags=idaapi.FC_PREDS)
    return fc
项目:idascripts    作者:ctfhacker    | 项目源码 | 文件源码
def bottom(func):
    '''Return the exit-points of the function ``func``.'''
    fn = by(func)
    fc = idaapi.FlowChart(f=fn, flags=idaapi.FC_PREDS)
    exit_types = (fc_block_type_t.fcb_ret,fc_block_type_t.fcb_cndret,fc_block_type_t.fcb_noret,fc_block_type_t.fcb_enoret,fc_block_type_t.fcb_error)
    return tuple(database.address.prev(n.endEA) for n in fc if n.type in exit_types)
项目:idascripts    作者:ctfhacker    | 项目源码 | 文件源码
def flow(func):
    '''Return a flow chart object for the function ``func``.'''
    fn = by(func)
    fc = idaapi.FlowChart(f=fn, flags=idaapi.FC_PREDS)
    return fc

# FIXME: document this
#def refs(func, member):
#    xl, fn = idaapi.xreflist_t(), by(func)
#    idaapi.build_stkvar_xrefs(xl, fn, member.ptr)
#    x.ea, x.opnum, x.type
#    ref_types = {
#        0  : 'Data_Unknown',
#        1  : 'Data_Offset',
#        2  : 'Data_Write',
#        3  : 'Data_Read',
#        4  : 'Data_Text',
#        5  : 'Data_Informational',
#        16 : 'Code_Far_Call',
#        17 : 'Code_Near_Call',
#        18 : 'Code_Far_Jump',
#        19 : 'Code_Near_Jump',
#        20 : 'Code_User',
#        21 : 'Ordinary_Flow'
#    }
#    return [(x.ea,x.opnum) for x in xl]
项目:idascripts    作者:ctfhacker    | 项目源码 | 文件源码
def bottom(func):
    '''Return the exit-points of the function ``func``.'''
    fn = by(func)
    fc = idaapi.FlowChart(f=fn, flags=idaapi.FC_PREDS)
    exit_types = (fc_block_type_t.fcb_ret,fc_block_type_t.fcb_cndret,fc_block_type_t.fcb_noret,fc_block_type_t.fcb_enoret,fc_block_type_t.fcb_error)
    return tuple(database.address.prev(n.endEA) for n in fc if n.type in exit_types)
项目:idascripts    作者:ctfhacker    | 项目源码 | 文件源码
def iterate(cls, func):
        '''Returns each idaapi.BasicBlock for the function ``func``.'''
        fn = by(func)
        fc = idaapi.FlowChart(f=fn, flags=idaapi.FC_PREDS)
        for bb in fc:
            yield bb
        return
项目:idascripts    作者:ctfhacker    | 项目源码 | 文件源码
def flow(func):
    '''Return a flow chart object for the function ``func``.'''
    fn = by(func)
    fc = idaapi.FlowChart(f=fn, flags=idaapi.FC_PREDS)
    return fc
项目:idascripts    作者:ctfhacker    | 项目源码 | 文件源码
def bottom(func):
    '''Return the exit-points of the function ``func``.'''
    fn = by(func)
    fc = idaapi.FlowChart(f=fn, flags=idaapi.FC_PREDS)
    exit_types = (fc_block_type_t.fcb_ret,fc_block_type_t.fcb_cndret,fc_block_type_t.fcb_noret,fc_block_type_t.fcb_enoret,fc_block_type_t.fcb_error)
    return tuple(database.address.prev(n.endEA) for n in fc if n.type in exit_types)
项目:idascripts    作者:ctfhacker    | 项目源码 | 文件源码
def flow(func):
    '''Return a flow chart object for the function ``func``.'''
    fn = by(func)
    fc = idaapi.FlowChart(f=fn, flags=idaapi.FC_PREDS)
    return fc

# FIXME: document this
#def refs(func, member):
#    xl, fn = idaapi.xreflist_t(), by(func)
#    idaapi.build_stkvar_xrefs(xl, fn, member.ptr)
#    x.ea, x.opnum, x.type
#    ref_types = {
#        0  : 'Data_Unknown',
#        1  : 'Data_Offset',
#        2  : 'Data_Write',
#        3  : 'Data_Read',
#        4  : 'Data_Text',
#        5  : 'Data_Informational',
#        16 : 'Code_Far_Call',
#        17 : 'Code_Near_Call',
#        18 : 'Code_Far_Jump',
#        19 : 'Code_Near_Jump',
#        20 : 'Code_User',
#        21 : 'Ordinary_Flow'
#    }
#    return [(x.ea,x.opnum) for x in xl]
项目:idascripts    作者:ctfhacker    | 项目源码 | 文件源码
def bottom(func):
    '''Return the exit-points of the function ``func``.'''
    fn = by(func)
    fc = idaapi.FlowChart(f=fn, flags=idaapi.FC_PREDS)
    exit_types = (fc_block_type_t.fcb_ret,fc_block_type_t.fcb_cndret,fc_block_type_t.fcb_noret,fc_block_type_t.fcb_enoret,fc_block_type_t.fcb_error)
    return tuple(database.address.prev(n.endEA) for n in fc if n.type in exit_types)
项目:idascripts    作者:ctfhacker    | 项目源码 | 文件源码
def iterate(cls, func):
        '''Returns each idaapi.BasicBlock for the function ``func``.'''
        fn = by(func)
        fc = idaapi.FlowChart(f=fn, flags=idaapi.FC_PREDS)
        for bb in fc:
            yield bb
        return
项目:idascripts    作者:ctfhacker    | 项目源码 | 文件源码
def flow(func):
    '''Return a flow chart object for the function ``func``.'''
    fn = by(func)
    fc = idaapi.FlowChart(f=fn, flags=idaapi.FC_PREDS)
    return fc

# FIXME: document this
#def refs(func, member):
#    xl, fn = idaapi.xreflist_t(), by(func)
#    idaapi.build_stkvar_xrefs(xl, fn, member.ptr)
#    x.ea, x.opnum, x.type
#    ref_types = {
#        0  : 'Data_Unknown',
#        1  : 'Data_Offset',
#        2  : 'Data_Write',
#        3  : 'Data_Read',
#        4  : 'Data_Text',
#        5  : 'Data_Informational',
#        16 : 'Code_Far_Call',
#        17 : 'Code_Near_Call',
#        18 : 'Code_Far_Jump',
#        19 : 'Code_Near_Jump',
#        20 : 'Code_User',
#        21 : 'Ordinary_Flow'
#    }
#    return [(x.ea,x.opnum) for x in xl]
项目:idascripts    作者:ctfhacker    | 项目源码 | 文件源码
def bottom(func):
    '''Return the exit-points of the function ``func``.'''
    fn = by(func)
    fc = idaapi.FlowChart(f=fn, flags=idaapi.FC_PREDS)
    exit_types = (fc_block_type_t.fcb_ret,fc_block_type_t.fcb_cndret,fc_block_type_t.fcb_noret,fc_block_type_t.fcb_enoret,fc_block_type_t.fcb_error)
    return tuple(database.address.prev(n.endEA) for n in fc if n.type in exit_types)
项目:idascripts    作者:ctfhacker    | 项目源码 | 文件源码
def flow(func):
    '''Return a flow chart object for the function ``func``.'''
    fn = by(func)
    fc = idaapi.FlowChart(f=fn, flags=idaapi.FC_PREDS)
    return fc
项目:idascripts    作者:ctfhacker    | 项目源码 | 文件源码
def bottom(func):
    '''Return the exit-points of the function ``func``.'''
    fn = by(func)
    fc = idaapi.FlowChart(f=fn, flags=idaapi.FC_PREDS)
    exit_types = (fc_block_type_t.fcb_ret,fc_block_type_t.fcb_cndret,fc_block_type_t.fcb_noret,fc_block_type_t.fcb_enoret,fc_block_type_t.fcb_error)
    return tuple(database.address.prev(n.endEA) for n in fc if n.type in exit_types)
项目:idascripts    作者:ctfhacker    | 项目源码 | 文件源码
def iterate(cls, func):
        '''Returns each idaapi.BasicBlock for the function ``func``.'''
        fn = by(func)
        fc = idaapi.FlowChart(f=fn, flags=idaapi.FC_PREDS)
        for bb in fc:
            yield bb
        return
项目:idascripts    作者:ctfhacker    | 项目源码 | 文件源码
def flow(func):
    '''Return a flow chart object for the function ``func``.'''
    fn = by(func)
    fc = idaapi.FlowChart(f=fn, flags=idaapi.FC_PREDS)
    return fc

# FIXME: document this
#def refs(func, member):
#    xl, fn = idaapi.xreflist_t(), by(func)
#    idaapi.build_stkvar_xrefs(xl, fn, member.ptr)
#    x.ea, x.opnum, x.type
#    ref_types = {
#        0  : 'Data_Unknown',
#        1  : 'Data_Offset',
#        2  : 'Data_Write',
#        3  : 'Data_Read',
#        4  : 'Data_Text',
#        5  : 'Data_Informational',
#        16 : 'Code_Far_Call',
#        17 : 'Code_Near_Call',
#        18 : 'Code_Far_Jump',
#        19 : 'Code_Near_Jump',
#        20 : 'Code_User',
#        21 : 'Ordinary_Flow'
#    }
#    return [(x.ea,x.opnum) for x in xl]
项目:choronzon    作者:CENSUS    | 项目源码 | 文件源码
def find_bbls(function_ea):
    '''
        yields all basic blocks that belong to the
        given function. The blocks are returned in
        a 2-tuple like:

            (start_address, end_address)

        Both start and end address are RELATIVE offsets
        from the image base.
    '''

    # get image base from IDA
    image_base = idaapi.get_imagebase()
    function_ea += image_base

    # get flow chart from IDA
    flow_chart = idaapi.FlowChart(
            idaapi.get_func(function_ea),
            flags=idaapi.FC_PREDS
            )

    # iterate through all basic blocks in
    # the current routine
    for block in flow_chart:
        start_addr = block.startEA - image_base
        end_addr = block.endEA - image_base
        if start_addr != end_addr:
            yield start_addr, end_addr
项目:idasec    作者:RobinDavid    | 项目源码 | 文件源码
def __init__(self, fun_addr):
        super(MyFlowGraph, self).__init__()
        self.fun = idaapi.get_func(fun_addr)
        self.startEA = self.fun.startEA
        self.endEA = self.fun.endEA
        for bb in idaapi.FlowChart(self.fun):
            self.__setitem__(bb.id, MyBasicBlock(bb))
        self._compute_links()
        self.edge_map = self.make_graph()
        self.shortest_path_map = self.dijkstra(self.edge_map)
        self.size = sum([x.size() for x in self.values()])
        self.viewer = MyFlowGraphViewer(self, "Extract(%s)" % idc.GetFunctionName(self.startEA))
项目:ropf    作者:kevinkoo001    | 项目源码 | 文件源码
def get_code_and_blocks(ea):
    """Extracts the control flow graph for the function at the given address.
    Returns a dictionary with the instructions (ea->insn.Instruction) and a list
    of the basic blocs (bbl.BasicBlock)."""
    code = {}
    blocks = {}
    ida_blocks = set(idaapi.FlowChart(idaapi.get_func(ea)))

    for bb in ida_blocks:

        # XXX: it seems that it's not a bug but inter-function jumps!
        if bb.startEA == bb.endEA: # skip that .. it's IDA's bug
            #print "skipping block %x : %x in func %x"%(bb.startEA, bb.endEA, ea)
            continue

        blocks[bb.startEA] = bbl.BasicBlock(bb.startEA, bb.endEA, {})

        for head in idautils.Heads(bb.startEA, bb.endEA):
            ibytes = idc.GetManyBytes(head, idc.ItemEnd(head) - head)
            spd = idc.GetSpd(head)
            code[head] = insn.Instruction(head, ibytes, spd)
            blocks[bb.startEA].instrs.append(code[head])
            next_head = idc.NextHead(head, bb.endEA)

            if idaapi.isFlow(idc.GetFlags(next_head)):
                code[head].succ.add(next_head)

        for suc_bb in (s for s in bb.succs() if s.startEA != s.endEA):
            #assume head is the last instruction of the block
            code[head].succ.add(suc_bb.startEA)

    for bb in (b for b in ida_blocks if b.startEA != b.endEA):
        for suc_bb in (s for s in bb.succs() if s.startEA != s.endEA):
            # a jump with zero offset (like, jz 0) gives two succs to the same bb
            if blocks[suc_bb.startEA] not in blocks[bb.startEA].successors:
                blocks[bb.startEA].successors.append(blocks[suc_bb.startEA])
        blocks[bb.startEA].successors.sort(key=lambda x: x.begin, reverse=True)

    #FIXME: find a better way ..
    for block in blocks.itervalues():
        if block.instrs[0].addr == ea:
            #print "found the entry!:", block.instrs
            block.instrs[0].f_entry = True
            block.type |= bbl.BasicBlock.ENTRY
            break
    else:
        print "BUG: could not find function entry in instrs!!"
    #print "blocks:", blocks

    return code, blocks.values()


#XXX: good test function in 0x070016E7 (BIB.dll)