C: return address of function (mac)

北城余情 提交于 2019-12-11 06:25:55

问题


following short c program:

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

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

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

a = 0x7fff5fbff9ac b = 0x7fff5fbff9a8

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

1....correct

then 0x7fff5fbff9a8 and the content:

2...correct

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

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

and its content was:

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

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


回答1:


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

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

However, your assumption is incorrect. You have compiled your code into a 64-bit executable (as evidenced by the size of the pointer you are printing). Per the OS X ABI, in a 64-bit Intel executable, the first few integer arguments are passed in register, not on the stack. Thus, immediately following the call, the stack actually looks like this:

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

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
// ...                             |

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.




回答2:


Firstly, &a + 4 is 0x7FFF5FBFF9B0, so you are looking one byte offset from where you think you are.

Secondly, the saved frame pointer lies between a and the return address, and this is the value you are seeing.




回答3:


What you are doing wrong is making a whole bunch of incorrect and random assumptions about the layout of the stack frame on your given platform. Where did you get that weird idea about "a + 4 bytes" location supposedly holding the return address?

If you really want to do this, get the documentation for your platform (or do some reverse engineering) to find out where and how exactly the return address is stored. Making random guesses and then asking other people why your random guesses do not produce results you for some reason expect is not exactly a productive way to do it.



来源:https://stackoverflow.com/questions/4390659/c-return-address-of-function-mac

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!