2

I found this piece of code:

goto*&L"\xfeeb";

It causes the program to hang forever, apparently through calling the x64 instructions 0xEB and 0xFE (in that order, due to x64's little-endianness). 0xEB is JMP according to the x86 Opcode and Instruction Reference.

I understand what the code does, and that it is equivalent to a function running the instructions 0xEB 0xFE, so it can also be written as int (*foo)() = L"\xfeeb"; foo();, or if we wanted to get really obfuscated, ((int(*)())L"\xfeeb")();. This is due to the fact that strings are marked executable by default on Linux.

However, goto is really strict. I don't understand why goto*&L"\xfeeb"; works at all, or what the crazy pointer magic *& is doing, or why the wide mark L is necessary. Can someone explain?

MD XF
  • 7,860
  • 7
  • 40
  • 71
  • If you want to try all these obfuscated snippets without compiling them individually yourself, you can use an online C compiler: [`goto*&L"\xfeeb";`](https://tio.run/##S9ZNT07@/z8zr0QhNzEzT6MsPzNFk6uaSwEI0vNL8rXUfJRiKtJSU5OUrLlq//8HAA) and [`int (*foo)() = L"\xfeeb"; foo();`](https://tio.run/##S9ZNT07@/z8zr0QhNzEzT6MsPzNFk6uaSwEIQIIaWmn5@Zoamgq2Cj5KMRVpqalJStZgWaC4hqY1V@3//wA) and [`((int(*)())L"\xfeeb")();`](https://tio.run/##S9ZNT07@/z8zr0QhNzEzT6MsPzNFk6uaSwEINDSAwhpamhqamj5KMRVpqalJSkCONVft//8A) – MD XF Feb 03 '18 at 03:48
  • 1
    Just a GCC [extension](https://stackoverflow.com/q/35236834/5267751) ([docs](https://gcc.gnu.org/onlinedocs/gcc-5.3.0/gcc/Labels-as-Values.html)). [Clang](https://tio.run/##S9ZNzknMS///PzOvRCE3MTNPoyw/M0WTq5pLAQjS80vytdR8lGIq0lJTk5SsuWr//wcA) doesn't support that. – user202729 Feb 03 '18 at 04:02
  • @user202729 still don't understand what part of GCC decided to allow that. – MD XF Feb 03 '18 at 04:03

1 Answers1

3

If I were to hazard a guess, the person who wrote the code was abusing GCC's Labels as Values extension. This feature was intended to make jump tables or portable JIT compilers or other things for which switch...case would be too slow.

C lets you goto a label.

label1:
...
goto label1;

GCC lets you take the address of a label with the && operator. To jump to an address foo you can just goto *foo;.

label1:
void *ptr = &&label1;
...
goto *ptr;

Just to recap, the C standard specifies that the argument following the goto statement be a token of type label. GCC adds an extension where the argument following the goto statement may also be a pointer to a pointer to executable code.

Therefore you can goto any piece of memory for which you have a pointer. On Linux, this includes string literals.

goto *&"\xe8\r\0\0\0Hello, World!Yj\1[j\rZj\4X\xcd\x80,\f\xcd\x80";

Try it online!

L"\xfeeb" is a wide string literal composed of characters of type wchar_t instead of char. Written as an old fashioned string literal, it would be "\xeb\xfe". I suspect the L in your string literal was serving the purpose of a MacGuffin.

ceilingcat
  • 671
  • 7
  • 11
  • "the person who wrote the code" [ಠ_ಠ](https://codegolf.stackexchange.com/a/104999/61563) – MD XF Mar 02 '18 at 05:02
  • The gcc extension permits `goto *foo;` where `foo` is of type `void*`. Due to a bug, it seems to allow `foo` to be of pointer types other than `void*`. See also [this question](https://stackoverflow.com/q/35236834/827263) and [my answer](https://stackoverflow.com/a/35237062/827263). – Keith Thompson Mar 03 '18 at 03:19