def main(): global cfgTree cfgTree = CFGTree() seg = idaapi.get_segm_by_name("__text") # Loop from segment start to end func_ea = seg.startEA # Get a function at the start of the segment (if any) func = idaapi.get_func(func_ea) if func is None: # No function there, try to get the next one func = idaapi.get_next_func(func_ea) seg_start = seg.startEA seg_end = seg.end_ea while func is not None and func.start_ea < seg_end: funcea = func.start_ea fflags = idc.get_func_flags(funcea) if (fflags & idc.FUNC_LIB) or (fflags & idc.FUNC_THUNK): continue # print("Function %s at 0x%x" % (idc.get_func_name(funcea), funcea)) flow = idaapi.FlowChart(idaapi.get_func(funcea), flags=idaapi.FC_PREDS) construct_cfg(flow, funcea, seg_start, seg_end) func = idaapi.get_next_func(funcea) cfgTree.print_deepest_path()
def __list_functions(cls): start,end = idaapi.cvar.inf.minEA,idaapi.cvar.inf.maxEA func = idaapi.get_func(start) if not func: func = idaapi.get_next_func(start) while func and func.startEA < end: startea = func.startEA yield startea func = idaapi.get_next_func(startea) return
def getFuncRanges(): funcs_addr = [] start = 0 next_func = idaapi.get_next_func(start) while next_func: size = next_func.size() if size > MIN_FUNC_SIZE: if size > MAX_FUNC_SIZE: size = MAX_FUNC_SIZE funcs_addr.append(next_func.start_ea - start) yield (next_func.start_ea, size) next_func = idaapi.get_next_func(next_func.start_ea)
def Functions(start, end): """ Get a list of functions @param start: start address @param end: end address @return: list of heads between start and end @note: The last function that starts before 'end' is included even if it extends beyond 'end'. """ funclist = [] func = idaapi.get_func(start) if func: funclist.append(func.startEA) ea = start while 1: func = idaapi.get_next_func(ea) if not func: break if func.startEA < end: funclist.append(func.startEA) ea = func.startEA else: break return funclist
def Functions(start=None, end=None): """ Get a list of functions @param start: start address (default: inf.minEA) @param end: end address (default: inf.maxEA) @return: list of heads between start and end @note: The last function that starts before 'end' is included even if it extends beyond 'end'. Any function that has its chunks scattered in multiple segments will be reported multiple times, once in each segment as they are listed. """ if not start: start = idaapi.cvar.inf.minEA if not end: end = idaapi.cvar.inf.maxEA # find first function head chunk in the range chunk = idaapi.get_fchunk(start) if not chunk: chunk = idaapi.get_next_fchunk(start) while chunk and chunk.startEA < end and (chunk.flags & idaapi.FUNC_TAIL) != 0: chunk = idaapi.get_next_fchunk(chunk.startEA) func = chunk while func and func.startEA < end: startea = func.startEA yield startea func = idaapi.get_next_func(startea)
def Functions(start=idaapi.cvar.inf.minEA, end=idaapi.cvar.inf.maxEA): """ Get a list of functions @param start: start address (default: inf.minEA) @param end: end address (default: inf.maxEA) @return: list of heads between start and end @note: The last function that starts before 'end' is included even if it extends beyond 'end'. Any function that has its chunks scattered in multiple segments will be reported multiple times, once in each segment as they are listed. """ func = idaapi.get_func(start) if not func: func = idaapi.get_next_func(start) while func and func.startEA < end: yield func.startEA func = idaapi.get_next_func(func.startEA)
def workaround_Functions(start=idaapi.cvar.inf.minEA, end=idaapi.cvar.inf.maxEA): """ Get a list of functions @param start: start address (default: inf.minEA) @param end: end address (default: inf.maxEA) @return: list of heads between start and end @note: The last function that starts before 'end' is included even if it extends beyond 'end'. """ func = idaapi.get_func(start) if not func: func = idaapi.get_next_func(start) while func and func.startEA < end: startea = func.startEA yield startea func = idaapi.get_next_func(startea) addr = startea while func and startea == func.startEA: addr = idaapi.next_head(addr, end) func = idaapi.get_next_func(addr)
def Functions(start=idaapi.cvar.inf.minEA, end=idaapi.cvar.inf.maxEA): """ Get a list of functions @param start: start address (default: inf.minEA) @param end: end address (default: inf.maxEA) @return: list of heads between start and end @note: The last function that starts before 'end' is included even if it extends beyond 'end'. """ func = idaapi.get_func(start) while func and func.startEA < end: yield func.startEA func = idaapi.get_next_func(func.startEA)
def Funcs(*args): """ Enumerate array items @param <range>: see getrange @return: list of all function starts """ (first, last)= getrange(args) # find first function head chunk in the range chunk = idaapi.get_fchunk(first) if not chunk: chunk = idaapi.get_next_fchunk(first) while chunk and chunk.startEA < last and (chunk.flags & idaapi.FUNC_TAIL) != 0: chunk = idaapi.get_next_fchunk(chunk.startEA) func = chunk while func and func.startEA < last: yield func.startEA func = idaapi.get_next_func(func.startEA)
def Funcs(*args): """ Enumerate array items @param <range>: see getrange @return: list of all function starts """ (first, last) = getrange(args) # find first function head chunk in the range chunk = idaapi.get_fchunk(first) if not chunk: chunk = idaapi.get_next_fchunk(first) while chunk and chunk.start_ea < last and (chunk.flags & idaapi.FUNC_TAIL) != 0: chunk = idaapi.get_next_fchunk(chunk.start_ea) func = chunk while func and func.start_ea < last: yield func.start_ea func = idaapi.get_next_func(func.start_ea)
def raw_main(p=True): global res # find .text section startEA first #text_startEA = None #for s in Segments(): # if SegName(s) == '.text': # text_startEA = s # break #if text_startEA is None: # text_startEA = 0 #f = idaapi.get_func(text_startEA) f = idaapi.get_next_func(0) fc = idaapi.FlowChart(f) while f: funcea = f.startEA fn = GetFunctionName(funcea) # if "Pl" in fn: # funcaddr = f.startEA # f = idaapi.get_next_func(funcaddr) # continue q = idaapi.qflow_chart_t("The title", f, 0, 0, idaapi.FC_PREDS) res.append("##############################\n") for n in xrange(0, q.size()): b = q[n] if p: res.append("%x - %x [%d]:\n" % (b.startEA, b.endEA, n)) for ns in xrange(0, q.nsucc(n)): res.append("SUCC: %d->%d\n" % (n, q.succ(n, ns))) pred_set = set() for ns in xrange(0, q.npred(n)): res.append("PRED: %d->%d\n" % (n, q.pred(n, ns))) pred_set.add(q.pred(n, ns)) if q.nsucc(n) == 0: # this is a block with no successors last_insn = None for h in Heads(b.startEA, b.endEA): last_insn = h if last_insn is None: continue insn = DecodeInstruction(last_insn) if idaapi.is_ret_insn(insn): continue disasm_str = GetDisasm(last_insn) if 'abort' in disasm_str or 'exit' in disasm_str or 'hlt' in disasm_str or '___stack_chk_fail' in disasm_str or '___assert_fail' in disasm_str: continue if idaapi.is_indirect_jump_insn(insn): # if this function ends with an indirect jump, it means ida failed to # determine the successors. We treat all blocks in this function as possible successors #with open('wierd_jump.txt', 'a') as tmp_f: # tmp_f.write(disasm_str + '\n') for tn in xrange(0, q.size()): res.append("SUCC: %d->%d\n" % (n, tn)) if tn not in pred_set: res.append("PRED: %d->%d\n" % (tn, n)) elif idaapi.is_call_insn(insn): # if this function ends with a call (not something like abort), it is somewhat wierd. # do not solve this temporarily #with open('wierd_call.txt', 'a') as tmp_f: # tmp_f.write(disasm_str + '\n') for tn in xrange(0, q.size()): res.append("SUCC: %d->%d\n" % (n, tn)) if tn not in pred_set: res.append("PRED: %d->%d\n" % (tn, n)) funcaddr = f.startEA f = idaapi.get_next_func(funcaddr)