Hello all.
I want to find the return address where execution should jump after returning from a function.
Say this is my code:

void foo(){
}
int main(){
 foo();
printf("After foo..");
return 0;
}

After foo() returns, how to find the rturn address where control will be passed?

Thank you....

Dani AI

Generated

Short answer: the return address is an implementation detail — it cannot be relied on portably and changing it is undefined and dangerous. was correct that small changes (compiler, optimization level, ABI, CPU) can move or remove the slot you think holds the return address.

Conceptually, a call puts a return address somewhere the callee can reach (often the stack), but modern ABIs and compilers complicate the picture: many arguments live in registers, compilers may omit the frame pointer, and optimizer rewrites can remove or inline frames. That is why experiments in this thread produced different outcomes ( got a segfault on Linux, saw different behavior on Windows) — the layout depends on OS, compiler, architecture and build options.

Safer, portable alternatives for changing control flow are recommended instead of manually patching stack memory: use function pointers or callbacks, or use the standard non-local-return facility (<csetjmp> / longjmp) that saves/restores execution context in a well-defined way (as suggested). For learning and debugging, prefer sandboxed VMs or capture-the-flag labs, build without optimizations (for predictable frames) and preserve frame pointers (for example, compile with a non-optimized build), and inspect frames with a debugger rather than guessing offsets.

Final caution: manually overwriting return addresses is undefined behavior, often blocked by modern mitigations (stack canaries, NX/DEP, ASLR, PIE), and can crash or create security vulnerabilities. If the goal is education, follow defensive, ethical practice and use controlled environments and documented interfaces instead of poking stack internals.

Recommended Answers

All 8 Replies

First, this is HIGHLY dependent on your current implementation. Change anything at all, and it might break.
It also means you need to tell us exactly what you have if you ever hope of a useful answer.

Second, why do you need to know, and what are you going to use the answer for (there's probably a better way).

Alright then.
I m trying to smash the stack.
I am trying to modify the return address so that i divert the execution elsewhere.
This is my code :

#include<stdio.h>

void function() {
   char buffer1[5];
   buffer1[0] = 'Z'; 	
   char *ret = &buffer1[0];
   printf("\nbuffer1 is pointing at : %p", &buffer1); 	
   printf("\nret is pointing at address : %p and contains: %c",ret, *ret);	
   ret = buffer1 + 8;//point to where return address is stored..hope this is correct
   printf("\nret is now pointing at address: %p",ret);
  
   (*ret) += 8;//modify return address 
  	
}

int main() {
  int x;
  x = 0;
  function();
  x = 5;//we are skipping the execution of this assignment....
  printf("\nx = %d\n",x);//shud print 0
  return 0;
}

heres the op:

buffer1 is pointing at : 0xbf85bd4f
ret is pointing at address : 0xbf85bd4f and contains: Z
ret is now pointing at address: 0xbf85bd57
x = 5

oh! and i am usng gcc on ubuntu

You will have to know how a stack frame is implemented on your system. I don't know if it is the same for all (or most) x86 systems, but from looking at this article on wikipedia it looks like it could be this:

+==========================+-+
| locals for function()    | |
+==========================+ |
| return address           |  -->  stack frame for function()
+==========================+ |
| parameters for function  | |
+==========================+-+

I did some toying around with C, and came up with this:

#include<stdio.h>

void somefunct();
void anotherfunct();

int main(){
    
    somefunct();

    printf("returned to main!\n");

    return 0;

}

void somefunct(){

    int *ptr = (int*)&ptr + 2;
    *ptr = (int)&anotherfunct;

}

void anotherfunct(){

    printf("I win!\n\n");

}

this prints the output:

~/c/t $ ./retaddr
I win!

Segmentation Fault
~/c/t $

The segmentation fault is because the stack is set up to return to main, and then return to the system once main completes. But since the return address is bashed to returned to yet another function, that function get's main's call stack. I have no idea what this does, but I'm assuming it is bad.

I had to play with the magic number (which turned out to be 2) for a bit, but I'm not exactly sure about why 2. I could play with it more and find out just how the stack frame looks, but I'll leave that up to you.

For fun, compile my code on your machine and see if you get identical output. Try it on a windows box. The behavior of this sort of thing depends heavily on the compiler and system.

I would play with this more but it's 2AM and time to get some rest.

Check out the library.

Don't mess with the stack. Otherwise you invite death.

Your function should be like this

void function() {
   int a;
   *(&a+2)+=0x07; 	
}

Yes I know the thread is almost a year old but this seemed like an interesting questions and there was no follow up

I ran your code in a Windows machine and it worked. No seg fault no nothing

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.