def gen_mod_graph(module_list, suffix): c = 0 g = set() while (c < len(module_list)): m = module_list[c] f = m.start while (f <= m.end): for xref in basicutils.FuncXrefsFrom(f): target = locate_module(module_list, xref) if (target): g.add((m.name, target.name)) f = basicutils.NextFunction(f) c += 1 root_name = basicutils.GetRootName() file = open(root_name + "_" + suffix + "_mod_graph.gv", "wb") file.write("digraph g {\n") for (node1, node2) in g: line = "%s -> %s\n" % (escape_for_graphviz(node1), escape_for_graphviz(node2)) file.write(line) file.write("}\n") file.close()
def print_results(function_list, module_list1, module_list2): c = 0 root_name = basicutils.GetRootName() file = open(root_name + "_cc_results.csv", "w") #write header file.write( "Function,Function #,LFA Score 1,LFA Score 2,LFA Total,LFA Edge,MC Edge,Function Name,Suggested Mod Name (LFA), Suggested Mod Name(MC),Source Str Ref\n" ) while (c < len(function_list)): f = function_list[c] fname = basicutils.GetFunctionName(f.loc) m1 = locate_module(module_list1, f.loc) m2 = locate_module(module_list2, f.loc) mname1 = m1.name mname2 = m2.name #hacky - should actually find the extent of the function #for now we'll just skip the last one if (c < (len(function_list) - 1)): nf = basicutils.NextFunction(f.loc) func_str_ref, score = modnaming.source_file_strings(f.loc, nf - 1) else: func_str_ref = "" line = "0x%08x, %d , %f, %f, %f, %d, %d, %s, %s, %s, %s\n" % ( f.loc, c + 1, f.score1, f.score2, f.total_score, f.edge[0], f.edge[1], fname, mname1, mname2, func_str_ref) file.write(line) c += 1
def gen_map_file(module_list, suffix): c = 0 root_name = basicutils.GetRootName() file = open(root_name + "_" + suffix + "_map.map", "wb") while (c < len(module_list)): m = module_list[c] mlen = basicutils.NextFunction(m.end) - m.start mlen_str = "0x%x" % mlen file.write("%s0x%016x%s %s\n" % (" .text".ljust(16), m.start, mlen_str.rjust(11), m.name)) c += 1 file.close()
def analyze(): global g_function_list global g_module_list #Define range to analyze #just do .text segment if we've got one #otherwise just start from the first function in DB start, end = basicutils.SegByName(".text") if (start == basicutils.BADADDR): start = basicutils.NextFunction(0) end = basicutils.BADADDR #Calculate LFA score for all functions func_call_weight(start, end) #Detect edges - object file boundaries edge_detect() return g_function_list, g_module_list
def func_call_weight(f_start, f_end): global g_function_list c = 1 f = f_start fe = f_end if f == 0: f = basicutils.NextFunction(0) f_end = basicutils.BADADDR prevscore = 0 prevscore_1 = 0 prevscore_2 = 0 z1 = 0 z2 = 0 #for each function in range while (f < fe): #get both LFA scores for the function score_1 = func_callers_weight(f) score_2 = func_callee_weight(f) #if both scores are 0 (i.e. no references for the function or all refs are above the threshold) #then skip the function altogether if (score_1 == 0) and (score_2 == 0): print "Skipping 0x%08x\n" % f prevscore_1 = 0 prevscore_2 = 0 z1 = 1 z2 = 1 finf = module.func_info(f, 0, 0) finf.lfa_skip = 1 g_function_list.append(finf) f = basicutils.NextFunction(f) continue #if 1st or 2nd score is zero, interpolate using previous score and an assumed negative linear slope #otherwise use the score if (score_1 == 0): score_1 = prevscore_1 - z1 * .4 z1 += 1 else: prevscore_1 = score_1 z1 = 1 if (score_2 == 0): score_2 = prevscore_2 - z2 * .4 z2 += 1 else: prevscore_2 = score_2 z2 = 1 total_score = score_1 + score_2 #Output scores in log window print "0x%08x, %d , %f, %f, %f" % (f, c, score_1, score_2, total_score) #Add scores to the global function score list finf = module.func_info(f, score_1, score_2) finf.lfa_skip = 0 g_function_list.append(finf) line = "0x%08x, %d , %f, %f, %f\n" % (f, c, score_1, score_2, total_score) f = basicutils.NextFunction(f) c += 1