函数指针声明语法混淆

时间:2015-11-10 06:14:33

标签: c pointers syntax function-pointers

我已经阅读并搜索了左右规则来解码函数指针。

例如:

int (*(*fun_one)(char *,double))[9][20];

是: fun_one是函数期望的指针(char *,double)和       返回指向int的数组(大小为20)的数组(大小为9)的指针。

那是什么

const char code[] = "\x31\xc0";

int main(){
     ((void(*)( ))code)();
}

" 代码是??返回指向函数的指针返回void ... ????那之后外面的()"

我对这一点感到困惑。

3 个答案:

答案 0 :(得分:3)

const char code[] = "\x31\xc0";

int main(){
     ((void(*)( ))code)();
}

这是它的工作原理。 code变量将衰减到第一个元素(\x31)的地址。

然后,该地址将被转换为采用不确定参数的函数的地址,并且不返回任何内容。

它涵盖整个((void(*)( ))code)位,并且到那里,你基本上构造了一个指向你的字符串的函数指针。

()然后只需调用您指向的函数。

如果那是你要定位的英特尔CPU,31 c0会反汇编到xor eax, eax,但是当它从缓冲区的末端运行时,我并不期待很多快乐,它很可能会崩溃。标记字符串结尾的\x00add指令的第一位,但至于之后的内容,则无法保证。

在字符串的末尾添加ret指令可能使其更安全,但您可能必须检查生成的调用本身的汇编程序代码以找出哪个< / em> ret应该被使用。

答案 1 :(得分:2)

这不是函数指针声明,它是一个函数指针 cast 和一个调用

对演员表进行了一段时间的着色,我们((某种类型)code)() - 也就是说,将code转换为某种类型(显然是函数指针),然后调用它。

那么演员阵容里面的类型是什么?它是void (*)()。换句话说,指向函数的指针返回void并且没有特别关注(它实际上可以接受参数,这要归功于C遗留,但在这种情况下它没有)。没什么,没什么。

*之后,如果这是一个声明,那么名称会去,但由于它是一个演员,所以这个类型是独立的,根本就没有名字。

答案 2 :(得分:2)

您感到困惑,因为它不是函数指针声明,而是函数调用后的强制转换。

(void (*)()) code 

这会将code转换为指向函数的指针,该函数使用未指定数量的参数返回任何内容。

((void (*)()) code) 

这是括号括起来的上面的整个表达式;结果是一个函数指针。

(void (*)() code)();

这将调用由转换点“创建”的函数指针所在的函数。

这实际上是试图调用code中构造的一些机器代码 - 这里你省略了其余部分,但31 c0是通常的xor eax,eax