Originally Posted by
0xIDE
hi, I've encountered this piece of code:
I ddin't really get how the whole thing works.
That does not work at all for me, but I'm pretty sure I know what someone (with very poor C skills) was trying to do.
Code:
int localStack;
int *pStack = &localStack, i;
for(i=0; i<x; i++)
{
*pStack = (int)&g;
pStack++;
}
Initially, pStack is set to the address of a local variable, "localStack". That's fine, but pointless since it is then set to a completely different address, that of the function g, which is not a stack address, it's a heap address. If you add this to the beginning of f():
Code:
fprintf(stderr,"%p %p\n", pStack, &g);
You'll (probably) see they are very different. So now pStack (really, pHeap, lol) starts to step through the program's memory. Most likely causing a segmentation fault.
Try this:
Code:
#include <stdio.h>
#include <unistd.h> // something else on windows
void g() {
int x = 0xdeadbeef;
}
int main() {
unsigned char *p = &g;
while (1) {
fprintf(stderr,"%p %x\n", p, *p);
p++;
sleep(1); // on windows, use sleep(500)
}
return 0;
}
This will cause a seg fault too eventually, when p steps off the end of the program's memory and the OS shuts it down. But before that, you will see something like this:
0x4005d4 55
0x4005d5 48
0x4005d6 89
[...]
0x4005db ef
0x4005dc be
0x4005dd ad
0x4005de de
0x4005df c9
0x4005e0 c3
[...]
Notice that the part in red is the value of x from g(). The bytes appear backward because that's how ints are stored ("little endian"). This is not really the stack, however, because this:
Originally Posted by
Babkockdood
The program and each subroutine has its own stack,
is not literally true. The program only has one stack, and when a function is called, that stack is filled with the values for that function, which come from the heap.
Now try this:
Code:
#include <stdio.h>
void g() {
int x = 0xdeadbeef, n;
unsigned char *p = &x;
while (1) {
n = *p;
fprintf(stderr,"stack %p %x\n", p, n);
if (*p == 0xde) break;
p++;
}
}
int main() {
unsigned char *p = &g;
while (1) {
fprintf(stderr,"heap %p %x\n", p, *p);
if (*p == 0xde) { // end of x
g();
return 0;
}
p++;
}
return 0;
}
Example output:
[...]
heap 0x40058d c7
heap 0x40058e 45
heap 0x40058f e0
heap 0x400590 ef
heap 0x400591 be
heap 0x400592 ad
heap 0x400593 de
stack 0x7fff9187f510 ef
stack 0x7fff9187f511 be
stack 0x7fff9187f512 ad
stack 0x7fff9187f513 de
Notice we are looking at the same value in memory with two different addresses, one when the variable is considered on the heap and then when it has been "placed" on the stack (or, more literally I think, the stack has been "placed" on it).