指针声明和函数调用中的奇怪C语法

3

在有人建议使用cdecl工具之前,我已经尝试过了。奇怪的是,大多数查询的语句都返回语法错误警告。

以下是我在网上找到的一个C程序,它只运行一段shellcode。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char **argv) {

char shellcode[] = "\xb0\x01\x31\xdb\xcd\x80";     

int (*func)();

func = (int (*)()) shellcode;
(int)(*func)();

return 0;

}

程序按预期工作,但C语法是我见过的最奇怪的。我会尽力解释它们。

int (*func)();

这个语句声明了func作为一个指向函数的指针(由'*'表示),该函数返回一个整数(由'()'表示)。
func = (int (*)()) shellcode;

这个语句将shellcode数组强制转换为指向返回int类型的函数(由“()”表示)的指针(由“(*)”表示),并将该指针分配给func。
(int)(*func)();

最终语句执行指针func所指向的函数(用'()'表示)并将结果强制转换为整数类型。

我认为这就是在这里发生的事情。如果有更有经验的C语言程序员看到我的解释中有任何错误,或者能提供其他或更具教育性的解释,我非常欢迎你的意见。

我从未像这样编写过变量初始化或函数调用,因此对展示的语法仍然感到相当困惑。如果您有更易读的方法来编写上面的代码,请也提供意见。

谢谢。


2
那看起来差不多正确。 - Some programmer dude
3
什么?首先,这段代码根本无法编译,因为字符串格式不正确。其次,这段代码没有任何方式可以运行而不出现某种类型的分段错误。这是因为:a. 你正在数据空间中执行代码。b. 这个“代码”是垃圾代码,不是真正的代码。 - thang
3
我已经对实际的 shellcode 进行了隐藏(由“...”表示)。程序编译成功,但会导致段错误。请注意,一旦执行了 shellcode,它会将某些 CPU 寄存器设置为特定的值,然后在 GDB 中检查这些值会显示出特定的信息。我不能透露 shellcode 的目的。是的,这也是我见过的最糟糕的指针使用方式;因此需要更专业的意见。 - AK-33
1
@thang,我已经混淆了实际的Shellcode... - David Ranieri
1
这个语句将shellcode数组强制转换为指针类型。你忘记了(或者没有提到)数组指针衰减,被强制转换的值是数组中第一个字符的地址。 - M.M
显示剩余3条评论
1个回答

2

这完全正确,但我不明白为什么它将返回值转换为int;我怀疑甚至写下这段代码的人对C函数指针语法也不是很自信。

在实际应用中,你可能会看到使用typedef来编写这段代码:

typedef (*funcT)();
funcT func = (funcT) shellcode;
(*func)();

我也很困惑为什么函数调用在声明和赋值后应该不需要进行强制类型转换,但却被转换为int。 - AK-33
1
我猜(int)是为了抑制编译器警告,因为表达式的结果未被使用。 - M.M
1
在这种情况下,惯用的方式是转换为void。 - Matteo Italia

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接