So I was working on a project and was a little bored and thought about how to break C really hard: Is it be possible, to trick the compiler in using jumps (goto) for a function call? - Maybe, I answered to myself. So after a bit of working and doing I realised, that some pointer stuff wasn't working correctly, but in an (at least for me) unexpected way: the goto wouldn't work as intended. After a little bit of experimenting, I came up with this stuff (comments removed, since I sometimes keep unused code in them, when testing):
//author: me, The Array :)
#include <stdio.h>
void * func_return();
void (*break_ptr)(void) = (void *)func_return;
void * func_return(){
printf("ok2\n");
break_ptr = &&test2;
return NULL;
if(0 == 1){
test2:
printf("sh*t\n");
}
}
void scoping(){
printf("beginning of scoping\n");
break_ptr();
printf("after func call #1\n");
break_ptr();
printf("!!!YOU WILL NOT SEE THIS!!!!\n");
}
int main(){
printf("beginning of programm\n");
scoping();
printf("ending programm\n");
}
I used gcc to compile this as I don't know any other compiler, that supports the use of that &&! My platform is windows 64 bit and I used that most basic way to compile this:
gcc.exe "however_you_want_to_call_it.c" -o "however_you_want_to_call_it.exe"
When looking over that code I expected and wanted it to print "sh*t\n" to the console window (of course the \n will be invisible). But it turns out gcc is somewhat too smart for me? I guess this comes, when trying to break something.. Infact, as the title says, it returns twice:
beginning of programm
beginning of scoping
ok2
after func call #1
ok2
ending programm
It does not return twice, like the fork function and propably prints the following stuff twice or sth., no it returns out of the function AND the function that called it. So after the second call it does not print "!!!YOU WILL NOT SEE THIS!!!!\n" to the console, but rather "ending programm", as it returned twice. (I am trying to amplify the fact, that the "ending programm" is printed, as the programm does not crash)
So the reason, why I posted that here, is the following: my questions..
- Why does it not go to/ jump to/ call to the actual test2 label and instead goes to the beginning of that function?
- How would I achieve the thing of my first question?
- Why does it return twice? I figured it is propably a compiler thing instead of a runtime thing, but I guess I'll wait for someones answer
- Can the same thing (the returning twice) be achieved the first time the function "break_ptr" is called, instead of the second time?
I do not know and do not care if this also works in c++.
Now I can see many ways this can be usefull, some malicious and some actually good. For example could you code an enterprise function, which returns your function. Enterprise solutions to problems tend to be weird, so why not make a function which returns your code, idk.. Yet it can be malicious, for example, when some code is returning unexpectatly or even without return values.. I can imagine this existing in a dll file and a header file which simply reads "extern void *break_ptr();" or sth.. did not test it. (Yet there are way crueler ways to mess with someone..)
I could not find this documented anywhere on the internet. Please send me some links or references about this, if you find some, I want to learn more about it.
If this is "just" a bug and someone of the gnu/gcc guys is reading this: Please do NOT remove it, as it is too much fun working with these things.
Thank you in advance for your answers and your time and I am sorry for making this so long. I wanted to make sure everything collected about this is in one place. (Yet still I am sorry if I missed something..)