I love Emacs. Sometimes it does things and you just go *phwoar*.
Case in point: move onto this Org src block and hit `C-c C-c` (having set the darn thing up...)
#+begin_src C :results verbatim :includes "<stdio.h> <stdlib.h>"
void trapdoor() {
printf("But how did we get over here?!\n");
exit(0);
}
void abracadabra() {
volatile void *buf[4];
printf("&buf: %p\n", buf);
printf("&main: %p\n", main);
printf("buf[6]: %p\n", buf[6]);
buf[6] = trapdoor; /* Nothing to see here... */
return;
}
printf("And for my next trick...\n");
abracadabra();
printf("...magic!\n");
#+end_src
#+RESULTS:
: And for my next trick...
: &buf: 0x7ffd148dddb0
: &main: 0x401166
: buf[6]: 0x7ffd148dde20
: ...magic!
: But how did we get over here?!
How on earth is that happening?!
More to the point, why after doing a perfectly trivial (and only a teensy bit magical) buffer overflow and return address hijack does the `...magic!` line get printed?
What on earth is going on?
With a bit of digging we can find the C code Emacs is actually compiling and running:
#include <stdio.h>
#include <stdlib.h>
int main() {
void trapdoor() {
printf("How did we get over here?!\n");
exit(0);
}
void abracadabra() {
volatile void *buf[4];
printf("&buf: %p\n", buf);
printf("&main: %p\n", main);
printf("buf[6]: %p\n", buf[6]);
buf[6] = trapdoor; /* Nothing to see here... */
return;
}
printf("And for my next trick...\n");
abracadabra();
printf("...magic!\n");
return 0;
}
Okay so it is wrapping the whole thing in a `main()` and then running it but are you allowed to declare functions in functions in C? I mean I guess that this runs at all you clearly can but y'know I've programmed C for coming on 15 years at this point and this is the first time I've seen that. It also explains why I can't add the prototypes for the functions or define them at the end of the block. Interesting though.
There is clearly more fun to be had here... and Emacs is magic