1

Function "Bob" calls function "Janice". Currently, I'm at an address in function "Janice" and can easily do idc.GetFunctionName(ea) to get the name Janice. However, I also want to get the caller function Bob's name. How would I go about doing this efficiently considering I'm currently within function Janice? Thanks.

3
  • 2
    Is it a debugging session or you trying to analyze the binary statically ?
    – w s
    Jul 19, 2016 at 6:04
  • And what architecture you are working with ? If it is ARM, you have an LR register which will show the return address in most cases.
    – w s
    Jul 19, 2016 at 8:51
  • Analyzing the binary statically was my goal and your answer covered it for me. Thanks
    – Eccmms
    Jul 19, 2016 at 12:56

2 Answers 2

1

Generally speaking this question as it asked is a bit ambiguous. The answer can be divided by 2 general parts, getting a caller in the debug session and determining the potential caller list during static analysis.

Getting a potential caller list during static analysis

As @blabb wrote in most cases it is possible and can be done with IDA scripting capabilities.

Here is IDAPython example which will print all references to the callee (which is equivalent to press x on the callee name in IDA) assuming that your cursor is within the "Janice" function:

    import idautils
    import idc
    print "Code references"
    for ref in idautils.CodeRefsTo(idc.GetFunctionAttr(idc.ScreenEA(), idc.FUNCATTR_START), 1):
           print ref
    print "Data references"
    for ref in idautils.DataRefsTo(idc.GetFunctionAttr(idc.ScreenEA(), idc.FUNCATTR_START)):
           print ref

Of course demangling should be applied to get a more human-readable name as @blabb wrote if needed.

It should be taken in account that this script (exactly as the pressing x on the callee) does not solve the indirect call issue, but shows all references to the function which may help to trace the indirect call.

Getting a specific caller during a debug session

This is a bit trickier and much more architecture dependent (for example in ARM you have LR register with return address which will help you in most cases if you stopped at the start of "Janice" function and it is not contaminated yet), you'll need to

  • Stop in the "Janice" function on the breakpoint
  • Determine the placement of return address
  • Conclude the specific caller from it

The script which will do it is a bit more complex and unfortunately I have no time to debug it for now, so I'll just list the IDAPython APIs which will probably help you to solve the problem:

idaapi.get_func(ea) # get the function object of func_t type
idaapi.get_frame(pfn) #gets the function frame structure of struc_t type
idaapi.frame_off_retaddr(pfn) # AFAIK gets the offset of return address of the structure
2

janice could have been called by bob or it could be a mob of other zillion prospective callers

you have to check each xrefto a sample showing the first xrefto below note you may need to demangle in some cases

auto ip,fname,fxref,fxrefname,fxrefdname;
ip = ScreenEA();
fname = GetFunctionName(ip);
fxref = RfirstB0(ip);
fxrefname = GetFunctionName(fxref);
Message("ScreenEa is in function %s and it is called first by  %s\n" , fname , fxrefname);
fxrefdname = Demangle(fxrefname,GetLongPrm(INF_LONG_DN));
Message("ScreenEa is in function %s and it is called first by  %s\n" , fname , fxrefdname);

result as screenshot (see the actual code xref and the message window)

ida_par_func

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.