在C(GCC)中对宽字符字符串调用goto

在C(GCC)中对宽字符字符串调用goto,c,gcc,binary,goto,opcode,C,Gcc,Binary,Goto,Opcode,我发现了这段代码: goto*&L"\xfeeb"; 它导致程序永久挂起,显然是通过调用x64指令0xEB和0xFE(由于x64的小端性,按此顺序)0xEB是符合以下条件的JMP 我理解代码的作用,它相当于运行指令的函数0xEB 0xFE,因此它也可以写成int(*foo)(=L“\xfeeb”;foo(),或者如果我们真的想弄糊涂,((int(*)L“\xfeeb”)()。这是因为在Linux上默认情况下字符串被标记为可执行 然而,goto确实很严格。我不明白为什么goto*&L“\

我发现了这段代码:

goto*&L"\xfeeb";
它导致程序永久挂起,显然是通过调用x64指令
0xEB
0xFE
(由于x64的小端性,按此顺序)
0xEB
是符合以下条件的JMP

我理解代码的作用,它相当于运行指令的函数
0xEB 0xFE
,因此它也可以写成
int(*foo)(=L“\xfeeb”;foo(),或者如果我们真的想弄糊涂,
((int(*)L“\xfeeb”)()。这是因为在Linux上默认情况下字符串被标记为可执行


然而,
goto
确实很严格。我不明白为什么
goto*&L“\xfeeb”
完全有效,或者疯狂的指针魔法
*&
正在做什么,或者为什么必须使用宽标记
L
。有人能解释一下吗?

如果我冒昧猜测,编写代码的人是在滥用。此功能旨在制作跳转表、便携式JIT编译器或其他
切换…case
速度太慢的东西

C允许您转到标签

label1:
...
goto label1;
GCC允许您使用
&&
运算符获取标签的地址。要跳转到地址
foo
,只需
goto*foo

label1:
void *ptr = &&label1;
...
goto *ptr;
简单回顾一下,C标准指定
goto
语句后面的参数是label类型的标记。GCC添加了一个扩展,其中
goto
语句后面的参数也可能是指向可执行代码的指针

因此,您可以
goto
任何有指针的内存块。在Linux上,这包括字符串文本

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


L“\xfeeb”
是由
wchar\u t
类型的字符组成的宽字符串文字,而不是
char
。作为旧式字符串文字编写,它应该是
“\xeb\xfe”
。我怀疑字符串文本中的
L
是用于a的。

如果您想尝试所有这些模糊的代码段,而不需要自己单独编译,您可以使用在线C编译器:和GCC()。不支持它。@user202729仍然不理解GCC的哪个部分决定允许它。“编写代码的人”GCC扩展允许
goto*foo其中
foo
属于
void*
类型。由于一个bug,它似乎允许
foo
为非
void*
的指针类型。另见和。