-
Stack and pointers
I have a simple program here:
Code:
void main()
{
int *p;
p = (int *)&p + 2; /* what???? */
(*p) = (int)somewhere_else;
}
I found that code on the net, and I'm wondering what that second instruction means. The program is supposed to change the function's return address. I would do the same thing like this:
Code:
void main()
{
int *p;
p = p + 2;
(*p) = (int)somewhere_else;
}
Could somebody just explain what that earlier example's 2nd instruction means. There's like &-operator in front of a pointer??? somewhere_else is just a pointer pointing somewhere else.
-
The only thing I can tell is that you don't get the same result when you do (int *)& to a pointer. You get the address of the memory of the pointer. That address you store it at the same pointer. So the pointer points itself. That is all. Don't know why you want to do this...
EDIT: Hmm, you generally get a seemingly "random" number when you get the address of the pointer. But just guessing here, the programmer of this code might know that the return address of main is stored 2 memory blocks (each memory block stores one int) away from where p is stored. Why? Don't know, but p is the only local variable so you know, it is possible the program behaves like that. So you store the return variable on p. Then you change the value of the return address to what you want, and I assume main returns there.
-
In your rewrite, the initial value of p is undefined, and then you add 2 to it. They won't work the same.
-
They're quite different, since the first example takes the address of the pointer (int**), and your second code takes the address stored inside the pointer (which is undefined).
This code is quite a hack, though. Typically function calls works by first pushing the return address to the stack and then jumping to the function. When returning, the return address is popped off the stack and jumped to again.
So what this code does is get the address of the local pointer p, which is located on the stack. Then it would add +8 to jump to the place where the return address is stored on the stack. Then it can overwrite that address. So when the function returns, it returns not to the caller function but something else.
STACK (example):
Return address (4 bytes) [0x0000000B]
...Something else... (4 bytes) [0x00000008]
Local pointer p (4 bytes) [0x00000004]