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?
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";
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.