在 C (GCC) 中的宽字符字符串上调用 goto
Calling goto on a wide-char string in C (GCC)
我找到了这段代码:
goto*&L"\xfeeb";
它导致程序永远挂起,显然是通过调用 x64 指令 0xEB
和 0xFE
(按此顺序,由于 x64 的小字节序)。 0xEB
是根据 x86 Opcode and Instruction Reference.
的 JMP
我明白代码做了什么,它相当于一个函数运行指令0xEB 0xFE
,所以它也可以写成int (*foo)() = L"\xfeeb"; foo();
,或者如果我们想要真正混淆,((int(*)())L"\xfeeb")();
。这是因为字符串在 Linux.
上默认标记为可执行
不过,goto
真的很严格。我完全不明白为什么 goto*&L"\xfeeb";
有效,或者疯狂的指针魔术 *&
在做什么,或者为什么宽标记 L
是必要的。有人可以解释一下吗?
如果我敢猜测,写代码的人在滥用 GCC's Labels as Values extension。此功能旨在制作跳转表或可移植 JIT 编译器或其他 switch...case
太慢的东西。
C 让你 goto
一个标签。
label1:
...
goto label1;
GCC 允许您使用 &&
运算符获取标签的地址。要跳转到地址 foo
,您只需 goto *foo;
.
label1:
void *ptr = &&label1;
...
goto *ptr;
回顾一下,C 标准指定 goto
语句后面的参数是 label 类型的标记。 GCC 添加了一个扩展,其中 goto
语句后面的参数也可以是一个 指向可执行代码 .
的指针
因此,您可以 goto
任何有指针的内存。在 Linux 上,这包括字符串文字。
goto *&"\xe8\r[=12=][=12=][=12=]Hello, World!Yj[j\rZjX\xcd\x80,\f\xcd\x80";
L"\xfeeb"
是一个 宽字符串文字 ,由 wchar_t
类型的字符组成,而不是 char
。写成老式的字符串文字,它将是 "\xeb\xfe"
。我怀疑你的字符串文字中的 L
是为了 MacGuffin.
我找到了这段代码:
goto*&L"\xfeeb";
它导致程序永远挂起,显然是通过调用 x64 指令 0xEB
和 0xFE
(按此顺序,由于 x64 的小字节序)。 0xEB
是根据 x86 Opcode and Instruction Reference.
我明白代码做了什么,它相当于一个函数运行指令0xEB 0xFE
,所以它也可以写成int (*foo)() = L"\xfeeb"; foo();
,或者如果我们想要真正混淆,((int(*)())L"\xfeeb")();
。这是因为字符串在 Linux.
不过,goto
真的很严格。我完全不明白为什么 goto*&L"\xfeeb";
有效,或者疯狂的指针魔术 *&
在做什么,或者为什么宽标记 L
是必要的。有人可以解释一下吗?
如果我敢猜测,写代码的人在滥用 GCC's Labels as Values extension。此功能旨在制作跳转表或可移植 JIT 编译器或其他 switch...case
太慢的东西。
C 让你 goto
一个标签。
label1:
...
goto label1;
GCC 允许您使用 &&
运算符获取标签的地址。要跳转到地址 foo
,您只需 goto *foo;
.
label1:
void *ptr = &&label1;
...
goto *ptr;
回顾一下,C 标准指定 goto
语句后面的参数是 label 类型的标记。 GCC 添加了一个扩展,其中 goto
语句后面的参数也可以是一个 指向可执行代码 .
因此,您可以 goto
任何有指针的内存。在 Linux 上,这包括字符串文字。
goto *&"\xe8\r[=12=][=12=][=12=]Hello, World!Yj[j\rZjX\xcd\x80,\f\xcd\x80";
L"\xfeeb"
是一个 宽字符串文字 ,由 wchar_t
类型的字符组成,而不是 char
。写成老式的字符串文字,它将是 "\xeb\xfe"
。我怀疑你的字符串文字中的 L
是为了 MacGuffin.