I am trying to play with a c code and see how I can access elements on the stack by just changing the value of the pointer.
In the following code, I have two variables - i and f - and a pointer to f. My foolish aim (it's just playing) was to change the pointer to i, without doing it directly, and giving i the address of a function as a value.
Now, it all worked just fine, and I managed to run the function by casting i to that function type.
size_t i = 0;
size_t f = 15;
size_t *ptr = &f;
/* why do I need that line?? */
printf("i is: %p\n", &i);
/* pointing ptr to i */
ptr = (size_t *)((size_t)ptr - sizeof(size_t));
/* making sure I can change the value of i */
*ptr = 12;
printf("i should be 12: %lu\n", i);
/* inserting the address of function to it */
*ptr = (size_t)function;
/* validating i has the same address as function */
printf("i has the value of: 0x%lx\n", i);
printf("address of function: %p\n", function);
/* calling the function through i */
typedef void (*func)(void);
printf("i is: %p\n", &i); you are taking the address of
i. This forces the compiler to actually give it an address.
Otherwise the compiler will likely notice that
size_t i = 0; sets
i to zero, and that never changes throughout the program. So it can just use
0 instead of
i for the rest of the program.
Your code here
/* pointing ptr to i */ ptr = (size_t *)((size_t)ptr - sizeof(size_t));
makes heavy assumptions on how the compiler places variables in memory. The language doesn't say anything about this, so the compiler can do anything it wants - including not placing a variable in memory at all.