I have written a simple IDAPython script to find all functions called from a specified function (either directly or indirectly). The problem is that I am unable to include imported functions in that list - only functions local to the application are included. Is there a way to get imported functions (with full names, e.g. KERNEL32.CreateFileA) included in that list?
I am using idautils.CodeRefsFrom(head, 0) to get a code reference, and I'm not getting anything for calls to imported functions. For example, idautils.CodeRefsFrom(head, 0) returns empty list for the following instruction:
0x004032A5 call ds:InterlockedIncrement
Also, is there a way to get the function's start address, provided you specify any address inside the function - something like nonexistent FindFuncStart(ea) function?
Below is the IDAPython script for finding all callees of a function:
def find_all_callees(start_ea):
'''Return a set of all callees called from the specified function.'''
callees = {}
visited = set([])
pending = set([start_ea])
while len(pending) > 0:
start_ea = pending.pop()
fname = GetFunctionName(start_ea)
if not fname: continue
callees[start_ea] = fname
visited.add(start_ea)
end_ea = FindFuncEnd(start_ea)
if end_ea == BADADDR: continue
all_refs = set([])
# For each defined element in the function.
for head in Heads(start_ea, end_ea):
# We are only interested in code
if not isCode(GetFlags(head)): continue
# Get the references made from the current instruction and keep only the ones
# not local to the function. Assume all such references are function calls.
refs = CodeRefsFrom(head, 0)
refs = set(filter(lambda x: not (x>=start_ea and x<=end_ea), refs))
all_refs |= refs
all_refs -= visited
pending |= all_refs
return callees
# main
ea = ScreenEA()
callees = find_all_callees(ea)
print '0x%08X: %s callees:' % (ea, callees[ea])
for ea in callees:
print ' 0x%08X: %s' % (ea, callees[ea])
Any help would be greatly appreciated.
Boris






