""" summary: dump function information description: Dump some of the most interesting bits of information about the function we are currently looking at. level: intermediate """ import binascii import ida_kernwin import ida_funcs def dump_flags(fn): "dump some flags of the func_t object" print("Function flags: %08X" % fn.flags) if fn.is_far(): print(" Far function") if not fn.does_return(): print(" Function does not return") if fn.flags & ida_funcs.FUNC_FRAME: print(" Function uses frame pointer") if fn.flags & ida_funcs.FUNC_THUNK: print(" Thunk function") if fn.flags & ida_funcs.FUNC_LUMINA: print(" Function info is provided by Lumina") if fn.flags & ida_funcs.FUNC_OUTLINE: print(" Outlined code, not a real function") def dump_regvars(pfn): "dump renamed registers information" assert ida_funcs.is_func_entry(pfn) print("Function has %d renamed registers" % pfn.regvarqty) for rv in pfn.regvars: print("%08X..%08X '%s'->'%s'" % (rv.start_ea, rv.end_ea, rv.canon, rv.user)) def dump_regargs(pfn): "dump register arguments information" assert ida_funcs.is_func_entry(pfn) print("Function has %d register arguments" % pfn.regargqty) for ra in pfn.regargs: print(" register #=%d, argument name=\"%s\", (serialized) type=\"%s\"" % ( ra.reg, ra.name, binascii.hexlify(ra.type))) def dump_tails(pfn): "dump function tails for entry chunk pfn" assert ida_funcs.is_func_entry(pfn) print("Function has %d tails" % pfn.tailqty) for i in range(pfn.tailqty): ft = pfn.tails[i] print(" tail %i: %08X..%08X" % (i, ft.start_ea, ft.end_ea)) def dump_stkpnts(pfn): "dump function stack points" print("Function has %d stack points" % pfn.pntqty) for i in range(pfn.pntqty): pnt = pfn.points[i] print(" stkpnt %i @%08X: %d" % (i, pnt.ea, pnt.spd)) def dump_frame(fn): "dump function frame info" assert ida_funcs.is_func_entry(fn) print("frame structure id: %08X" % fn.frame) print("local variables area size: %8X" % fn.frsize) print("saved registers area size: %8X" % fn.frregs) print("bytes purged on return : %8X" % fn.argsize) print("frame pointer delta : %8X" % fn.fpd) def dump_parents(fn): "dump parents of a function tail" assert ida_funcs.is_func_tail(fn) print("owner function: %08X" % fn.owner) print("tail has %d referers" % fn.refqty) for i in range(fn.refqty): print(" referer %i: %08X" % (i, fn.referers[i])) def dump_func_info(ea): "dump info about function chunk at address 'ea'" pfn = ida_funcs.get_fchunk(ea) if pfn is None: print("No function at %08X!" % ea) return print("current chunk boundaries: %08X..%08X" % (pfn.start_ea, pfn.end_ea)) dump_flags(pfn) if (ida_funcs.is_func_entry(pfn)): print ("This is an entry chunk") dump_tails(pfn) dump_frame(pfn) dump_regvars(pfn) dump_regargs(pfn) dump_stkpnts(pfn) elif (ida_funcs.is_func_tail(pfn)): print ("This is a tail chunk") dump_parents(pfn) ea = ida_kernwin.get_screen_ea() dump_func_info(ea)