### Walk the functions # Get the segment's starting address ea = ScreenEA() # Loop through all the functions for function_ea in Functions(SegStart(ea), SegEnd(ea)): # Print the address and the function name. print hex(function_ea), GetFunctionName(function_ea)
### Going through the segments segments = dict() # For each segment for seg_ea in Segments(): data = [] # For each byte in the address range of the segment for ea in range(seg_ea, SegEnd(seg_ea)): # Fetch byte data.append(chr(Byte(ea))) # Put the data together segments[SegName(seg_ea)] = ''.join(data) # Loop through the dictionary and print the segment's names # and their sizes for seg_name, seg_data in segments.items(): print seg_name, len(seg_data)
### Indegree and outdegree of functions from sets import Set # Get the segment's starting address ea = ScreenEA() callers = dict() callees = dict() # Loop through all the functions for function_ea in Functions(SegStart(ea), SegEnd(ea)): f_name = GetFunctionName(function_ea) # Create a set with all the names of the functions calling (referring to) # the current one. callers[f_name] = Set(map(GetFunctionName, CodeRefsTo(function_ea, 0))) # For each of the incoming references for ref_ea in CodeRefsTo(function_ea, 0): # Get the name of the referring function caller_name = GetFunctionName(ref_ea) # Add the current function to the list of functions # called by the referring function callees[caller_name] = callees.get(caller_name, Set()) callees[caller_name].add(f_name) # Get the list of all functions functions = Set(callees.keys()+callers.keys()) # For each of the functions, print the number of functions calling it and # number of functions being called. In short, indegree and outdegree for f in functions: print '%d:%s:%d' % (len(callers.get(f, [])), f, len(callees.get(f, [])))
### Nmemonics histogram mnemonics = dict() # For each of the segments for seg_ea in Segments(): # For each of the defined elements for head in Heads(seg_ea, SegEnd(seg_ea)): # If it's an instruction if isCode(GetFlags(head)): # Get the mnemonic and increment the mnemonic # count mnem = GetMnem(head) mnemonics[mnem] = mnemonics.get(mnem, 0)+1 # Sort the mnemonics by number of occurrences sorted = map(lambda x:(x[1], x[0]), mnemonics.items()) sorted.sort() # Print the sorted list for mnemonic, count in sorted: print mnemonic, count
### Collecting function chunks function_chunks = [] #Get the tail iterator func_iter = func_tail_iterator_t(get_func(ea)) # While the iterator?s status is valid status = func_iter.main() while status: # Get the chunk chunk = func_iter.chunk() # Store its start and ending address as a tuple function_chunks.append((chunk.startEA, chunk.endEA)) # Get the last status status = func_iter.next()
### Cyclomatic complexity import os from sets import Set def cyclomatic_complexity(function_ea): """Calculate the cyclomatic complexity measure for a function. Given the starting address of a function, it will find all the basic block's boundaries and edges between them and will return the cyclomatic complexity, defined as: CC = Edges - Nodes + 2 """ f_start = function_ea f_end = FindFuncEnd(function_ea) edges = Set() boundaries = Set((f_start,)) # For each defined element in the function. for head in Heads(f_start, f_end): # If the element is an instruction if isCode(GetFlags(head)): # Get the references made from the current instruction # and keep only the ones local to the function. refs = CodeRefsFrom(head, 0) refs = Set(filter(lambda x: x>=f_start and x<=f_end, refs)) if refs: # If the flow continues also to the next (address-wise) # instruction, we add a reference to it. # For instance, a conditional jump will not branch # if the condition is not met, so we save that # reference as well. next_head = NextHead(head, f_end) if isFlow(GetFlags(next_head)): refs.add(next_head) # Update the boundaries found so far. boundaries.union_update(refs) # For each of the references found, and edge is # created. for r in refs: # If the flow could also come from the address # previous to the destination of the branching # an edge is created. if isFlow(GetFlags(r)): edges.add((PrevHead(r, f_start), r)) edges.add((head, r)) return len(edges) - len(boundaries) + 2 def do_functions(): cc_dict = dict() # For each of the segments for seg_ea in Segments(): # For each of the functions for function_ea in Functions(seg_ea, SegEnd(seg_ea)): cc_dict[GetFunctionName(function_ea)] = cyclomatic_complexity(function_ea) return cc_dict # Wait until IDA has done all the analysis tasks. # If loaded in batch mode, the script will be run before # everything is finished, so the script will explicitly # wait until the autoanalysis is done. autoWait() # Collect data cc_dict = do_functions() # Get the list of functions and sort it. functions = cc_dict.keys() functions.sort() ccs = cc_dict.values() # If the environment variable IDAPYTHON exists and its value is 'auto' # the results will be appended to a data file and the script will quit # IDA. Otherwise it will just output the results. if os.getenv('IDAPYTHON') == 'auto': results = file('example5.dat', 'a+') results.write('%3.4f,%03d,%03d %s\n' % ( sum(ccs)/float(len(ccs)), max(ccs), min(ccs), GetInputFile())) results.close() Exit(0) else: # Print the cyclomatic complexity for each of the functions. for f in functions: print f, cc_dict[f] # Print the maximum, minimum and average cyclomatic complexity. print 'Max: %d, Min: %d, Avg: %f' % (max(ccs), min(ccs), sum(ccs)/float(len(ccs)))
for virus in virus/*.idb; do IDAPYTHON='auto' idal -A -OIDAPython:example5.py $virus; done
### Visualizing Binaries from sets import Set import pydot # Get the segment's starting address ea = ScreenEA() callers = dict() callees = dict() # Loop through all the functions for function_ea in Functions(SegStart(ea), SegEnd(ea)): f_name = GetFunctionName(function_ea) # For each of the incoming references for ref_ea in CodeRefsTo(function_ea, 0): # Get the name of the referring function caller_name = GetFunctionName(ref_ea) # Add the current function to the list of functions # called by the referring function callees[caller_name] = callees.get(caller_name, Set()) callees[caller_name].add(f_name) # Create graph g = pydot.Dot(type='digraph') # Set some defaults g.set_rankdir('LR') g.set_size('11,11') g.add_node(pydot.Node('node', shape='ellipse', color='lightblue', style='filled')) g.add_node(pydot.Node('edge', color='lightgrey')) # Get the list of all functions functions = Set(callees.keys()+callers.keys()) # For each of the functions and each of the called ones, add # the corresponding edges. for f in functions: if callees.has_key(f): for f2 in callees[f]: g.add_edge(pydot.Edge(f, f2)) # Write the output to a Postscript file g.write_ps('example6.ps')
There are 31,320 total registered users.
[+] expand