如何在进程的当前栈中获取当前栈中已经压栈了的函数名?

发布于 2022-10-15 08:26:54 字数 677 浏览 23 评论 0

我的问题如下:
现在别人已经有了一个程序,然后我在别人程序里面的任意一个函数中调用我的函数myfunciton,在myfunction中我要能获取到最近三层或者四层的调用关系。
比如别人程序中有如下调用关系的2个函数function1,fucntion2,然后在其中function2中调用myfunction函数,在myfunction函数中需要获取到函数的调用关系。
void function1()
{
  function2();
}

void function2()
{
  myfunction();
}

void myfunction()
{
   
}
  我需要在myfunction函数中获取到调用链的关系,即如何在myfunction中唯一标识function1--function2--myfunction这
一条调用链,也可以说是在myfucntion函数中获取到function1和function2的函数名。

  我的想法是在myfunction函数中采用内嵌汇编,看是否可以获取到当前的调用关系链,但是我现在还没有找到具体可行的方案,  希望有高人指点!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

爱格式化 2022-10-22 08:26:54

函数名字不入栈吧?在汇编中call funtion 只是一句伪代码,跑的时候就会把funtion的地址替换

单身情人 2022-10-22 08:26:54

谢谢你的回帖~~

是的,压入栈的只是函数的地址!其实并不一定需要准确的知道函数名,只要能知道唯一标识这条链的东西就是可以的。

云醉月微眠 2022-10-22 08:26:54

回复 1# SCU_Snowkey

试试   __builtin_return_address吧。

我还不会笑 2022-10-22 08:26:54

楼主说的是backtrace吧?
man backtrace

何以心动 2022-10-22 08:26:54

vxworks中的tt命令就是干这事的。

我猜大概原理是:在你的栈中,向高地址找 pushl %ebp ; movl %esp, %ebp 这样的opcode,如果找到,则说明是在进行函数调用,那么这两条opcode的再往上一条地址就是调用你的函数的时压栈的返回值,通过找这个返回值在符号表中的位置就能找到对应的函数符号,也就是调用你的函数的名字。

魔法唧唧 2022-10-22 08:26:54

这个问题已经差不多解决了,也给大家分享下我所知道的,不对的请大家指正。

4楼的朋友说的很对啊,使用__builtin_return_address是可以获取到函数返回地址的,这里所说的返回地址并不是函数的地址,是我们使用call function以后要压栈的下一条指令的地址,但是根据此地址查找符号文件找到距此地址最近的函数名称。我在gdb调试中发现,当__builtin_return_address的参数为零的时候返回值实际上是调用它的函数(caller)中的地址,所以我理解这里参数为零是在当前函数栈中存储的返回地址,依次类推。

另外我也用汇编实现了下类似__builtin_return_address的功能,也请大家指正!
int get_return_address(int iLevel)
{
        __asm__("pushl %%ebx\n\t"
                "movl %%ebp,%%eax\n\t"
                "movl 12(%%esp),%%ebx\n\n"
                "__next:\n\t"
                "test %%ebx,%%ebx\n\t"
                "je __break\n\t"
                "dec %%ebx\n\t"
                "movl (%%eax),%%eax\n\t"
                "jmp __next\n\n"
                "__break:\n\t"
                "movl 4(%%eax),%%eax\n\t"
                "pop %%ebx\n\t"
                ::
        );
}

小弟还有个问题,希望有高人能指点下!
在我们程序运行的当前栈中,如何定位到main函数,因为我们c程序执行都是从main函数开始执行的,我们通过在栈中找上一层函数的地址,如何判断哪一层已经是main函数的栈了呢?就像gdb里面一样,使用bt(backtrace)以后我们可以得到当前栈的信息。

情绪失控 2022-10-22 08:26:54

楼主可以读取符号文件的话,就可以找到main的虚拟地址吧。 Back Trace顺次找到函数返回的地址,应该能找到离main比较近的那个地址,就可以找到main的栈帧了吧。 如果不查找符号文件的话,找到离地址0x08048000最近的那个返回地址也差不多可以定位到main的栈帧吧。

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文