C:的函数返回地址(MAC) [英] C: return address of function (mac)

查看:121
本文介绍了C:的函数返回地址(MAC)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下简短C程序:

void foo(int a, int b) {
        printf("a = %p b = %p\n", &a, &b);
}

main() {
        foo(1, 2);
}

好了,现在我用gdb查看此程序。我得到的输出:

ok, now I used gdb to view this program. I got as output:

a = 0x7fff5fbff9ac b = 0x7fff5fbff9a8

和输出后停止执行(中富())。现在我检查0x7fff5fbff9ac,内容是:

and stopped execution after the output (in foo()). now I examined 0x7fff5fbff9ac and the content was:

1 ....正确

然后0x7fff5fbff9a8和内容:

then 0x7fff5fbff9a8 and the content:

2 ......正确

2...correct

现在我想查看函数的返回地址,并检查(一个+4字节)其中:

now I wanted to view the return address of the function and examined (a + 4 bytes) with:

X / G 0x7fff5fbff9b1(8字节!地址,因此G(巨字))

x/g 0x7fff5fbff9b1 (8 bytes!! address, therefore "g" (giant word))

和它的含量是:

(gdb) x/g 0x7fff5fbff9b1
0x7fff5fbff9b1: 0xd700007fff5fbff9

但是:这不是RETURN ADR与主!哪里是我的错吗?

BUT: THIS IS NOT THE RETURN ADR FROM MAIN! where is my fault?

推荐答案

有错误的假设的一大堆你的问题。

There are a whole bunch of faulty assumptions in your question.

您是假定整数参数在栈立即返回地址上方传递(因为它们是在的许多的 - 不是的所有的 - 86下的ABI默认调用约定)。如果是这样的话,那么紧随其后的电话,你的筹码应该是这样的:

You're assuming that integer arguments are passed on the stack immediately above the return address (as they are in many--not all--x86 ABIs under the default calling conventions). If this were the case, then immediately following the call, your stack would look like this:

// stack frame of main( )
// ...
value of b
value of a
return address <--- stack pointer

然而,你的假设是不正确。你编译你的code到64位可执行文件(由您打印的指针的大小为证)。每OS X的ABI,在64位Intel可执行文件,最初的几个整数参数传递寄存器,而不是堆栈。于是,马上打电话,堆栈以下的真正的是这样的:

// stack frame of main( )
// ...
return address <--- stack pointer

既然你把地址 A B ,他们将在之前的一些点被写入到协议栈调用的printf()(除非该编译器的真正的聪明,意识到它实际上并不需要用手的printf()有效指针,因为它不会使用的价值指向,但是这将是pretty邪恶的优化走),但你真的不知道他们会相对到返回地址;事实上,由于64位ABI提供的红色区域,你甚至不知道他们是否是堆栈指针上方或下方。因此,在你打印出的a和b的地址的时候,你的筹码看起来是这样的:

Since you take the address of a and b, they will be written to the stack at some point before the call to printf( ) (unless the compiler is really clever, and realizes that it doesn't actually need to hand printf( ) valid pointers because it won't use the value pointed to, but that would be pretty evil as optimizations go), but you really don't know where they will be relative to the return address; in fact, because the 64-bit ABI provides a red zone, you don't even know whether they're above or below the stack pointer. Thus, at the time that you print out the address of a and b, your stack looks like this:

// stack frame of main( )
// ...
return address                     |
// ...                             |
// a and b are somewhere down here | <-- stack pointer points somewhere in here
// ...                             |

在一般情况下,C语言标准只字未提堆栈的布局,或甚至认为,需要有一个堆栈在所有即可。你不能得到这样的信息,从C code的轻便时尚。

In general, the C language standard says nothing about stack layouts, or even that there needs to be a stack at all. You cannot get this sort of information in any portable fashion from C code.

这篇关于C:的函数返回地址(MAC)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆