💾 Archived View for bad-gateway.smol.pub › 20220119 captured on 2023-01-29 at 15:38:47. Gemini links have been rewritten to link to archived content

View Raw

More Information

⬅️ Previous capture (2022-03-01)

-=-=-=-=-=-=-

2022-01-19: Emacs is magic

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