所以对于这段代码我怎样才能使用局部变量" x"在函数fun()中查找存储在fun()的堆栈返回地址的位置(启用了aslr)?
void fun()
{
int x;
}
int main()
{
printf("blah blah blah");
}
答案 0 :(得分:1)
我不认为单独使用x
查找返回地址是可能的,但我会尽力让您亲近。
进入函数时,堆栈看起来像
*---------------------*
* return address *
*---------------------*
* prev base pointer *
*---------------------*
* *
* local vars *
* *
*---------------------*
在这种情况下,唯一的局部变量是x,因此堆栈看起来像:
*---------------------*
* return address *
*---------------------* <-- addr of return address
* prev base pointer *
*---------------------*
* x *
*---------------------* <-- addr of x
您可以通过
获取x的地址printf("%p", (void*)&x)
然后你只需要找到x和返回地址之间的字节数。假设没有byte alignment/padding之间的距离应该是x的大小+前一个基指针的大小。在32位机器上,每个值应为~32位或4个字节,但为了确保您可以使用sizeof
sizeof(x)
sizeof(unsigned long*) // This is the tpye of the base pointer
将所有这些结合在一起
unsigned long* x_addr = (unsigned long*) &x;
ret_addr = x_addr + sizeof(x) + sizeof(unsignled long*);
答案 1 :(得分:0)
考虑添加到您的程序:
void callfun()
{
return fun(); // Return address pushed on stack after callfun()'s.
}
int main()
{
fun(); // Return address pushed on stack after main()'s.
printf("blah blah blah");
}
返回地址的不同取决于堆栈在fun()调用点的深度。即使这些假设也基于一个C编译器实现,它具有一组特定的编译器参数,这些参数可能不会从该编译器的版本产生相同的结果。 C标准没有规定这些细节。
答案 2 :(得分:0)
您不会在示例中显示任何返回的内容。
通常,函数返回值存储在寄存器中。因此,没有地址。对于太大而无法存储在寄存器(例如,结构)中的值,通常会将一个隐藏参数传递给函数。
如果您正在讨论对func()的特定调用返回的地址,则需要知道特定处理器的调用帧格式。然后你可以用汇编语言编写一个函数来扫描堆栈,找到地址的前一个调用帧。