如何在不使用任何指针或&的情况下查找函数的地址

时间:2014-06-23 04:26:49

标签: c

我在接受采访时被要求在不使用任何指针或&amp ;.的情况下找出函数的地址。我无法回答他的问题,但当我与他核实答案时,他给出了以下示例,其中函数f1()调用函数f2()。因此,当函数f2()被调用时,堆栈存储的返回地址只是函数f1()的地址。在函数f2()中,我们可以读取堆栈,然后找出存储在堆栈中的地址,该地址是函数f1()。任何人都可以详细解释它如何从函数f2()中读取堆栈并找出f1()的地址。

int main()
{
    f1();
    return 0;
}
void f1()
{
    f2();
}

1 个答案:

答案 0 :(得分:4)

需要注意的是,此方法完全不可移植为T.C.提及,并且如果打开优化几乎肯定不会起作用的附加警告,您可以通过读取缓冲区的末尾从堆栈中读取返回地址,如下例所示。

int main()
{
    f1();
    return 0;
}
void f1()
{
    f2();
}
void f2() {
    char buf[4];
    printf("%p\n", *(void**)(buf + 8));
}

请注意,上面的数字8会因操作系统,体系结构和编译器填充而异,因此您很可能必须尝试各种不同的数字才能使其正常工作。 对于该示例,8的选择假设填充到4字节边界,并且在32位系统上填充4字节指针。

您还必须确保优化已关闭

之所以这样做是因为函数调用之后的堆栈结构看起来像这样。

|Return Address|
|Saved Frame Pointer|
|Local Variables|

观察返回地址的地址高于本地变量。这就是为什么读取缓冲区的末尾将允许您可能读取返回地址。

这与优化打破的原因是编译器可能决定内联一个或两个函数,或者意识到其中一个函数完全没有做任何事情并完全优化函数调用,这就抛弃了关于​​堆栈的假设。 / p>