This is almost certainly an XY problem, you didn't say what you really want to do.
Anyway, here is sample code that modifies the return address:
#include <stdio.h>
#include <stdlib.h>
void bar()
{
puts("entered the bar ;)");
exit(0);
}
void** search(void** addr, void* value) __attribute__((noinline));
void** search(void** addr, void* value)
{
while(*addr != value) addr++;
return addr;
}
void foo() __attribute__((noinline));
void foo()
{
void** p = search((void**)&p, __builtin_return_address(0));
*p = bar;
}
int main()
{
foo();
return 0;
}
See it in action.
Obviously foo
must not be inlined for it to even have a return address, and I had to split out search
into its own function for some obscure optimization issue whereby the compiler would otherwise remove the write to the return address. Searching for the return address like this makes it more tolerant of stack layout differences than if you just hardcoded some specific offset from a local variable.