查找调用函数的函数名

逆向工程 艾达 蟒蛇
2021-07-05 12:46:52

函数“Bob”调用函数“Janice”。目前,我在函数“Janice”中的一个地址,可以轻松地执行 idc.GetFunctionName(ea) 来获取名称 Janice。但是,我也想获得调用者函数 Bob 的名字。考虑到我目前在 Janice 职能部门内,我将如何有效地执行此操作?谢谢。

2个回答

珍妮丝可能是被鲍勃打来的,也可能是其他无数潜在来电者的暴徒

您必须检查每个外部参照的样本,显示下面的第一个外部参照,请注意在某些情况下您可能需要进行修饰

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);

结果作为屏幕截图(请参阅实际代码外部参照和消息窗口)

ida_par_func

一般来说,这个问题问的有点模棱两可。答案可以分为 2 个一般部分,在调试会话中获取调用者和在静态分析期间确定潜在调用者列表。

在静态分析期间获取潜在呼叫者列表

正如@blabb 在大多数情况下所写的那样,这是可能的,并且可以通过 IDA 脚本功能来完成。

这是 IDAPython 示例,x假设您的光标位于“Janice”函数内,它将打印对被调用者的所有引用(相当于在 IDA 中按下被调用者名称):

    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

当然,如果需要的话,应该像@blabb 写的那样应用 demangling 来获得一个更易读的名字。

应该考虑到这个脚本(正好是x对被调用者的按压)并没有解决间接调用问题,而是显示了对可能有助于跟踪间接调用的函数的所有引用。

在调试会话期间获取特定调用者

这有点棘手,而且更依赖于体系结构(例如,在 ARM 中,您有带有返回地址的 LR 寄存器,如果您在“Janice”函数的开始处停止并且它还没有受到污染,这将在大多数情况下为您提供帮助),您我需要

  • 停在“Janice”函数的断点处
  • 确定退货地址的位置
  • 从中得出特定的调用者

执行它的脚本有点复杂,不幸的是我现在没有时间调试它,所以我只列出 IDAPython API,它们可能会帮助您解决问题:

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