我今天在一些fb配置文件中看到了这段代码,并且无法理解这是什么以及它是如何工作的: -
(*(void(*)()) shellcode)()
有人可以解释一下,上面的代码是什么意思?
下面的完整代码片段: -
#include <stdio.h>
#include <string.h>
char *shellcode = "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69"
"\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80";
int main(void)
{
fprintf(stdout,"Length: %d\n",strlen(shellcode));
(*(void(*)()) shellcode)();
return 0;
}
答案 0 :(得分:8)
它是函数指针的强制转换(没有返回结果且没有参数)。我更喜欢使用typedef
来定义这些函数的签名:
typedef void plainsig_t(void);
然后简单地编码
(*(plainsig_t*)shellcode) ();
对于函数指针,您不需要取消引用它们,因此只需编写代码就可以了:
((plainsig_t*) shellcode) ();
基本上调用其机器代码位于shellcode
内存区域内的函数。
答案 1 :(得分:6)
这是C和C ++不同的地方。
在C中,它表示指向函数的指针,该函数返回void并获取未指定数量的未指定类型的参数。
在C ++中,它表示指向返回void且不带参数的函数的指针。
表达式作为一个整体取shellcode
的地址,将其转换为指向函数类型的指针,然后调用该函数 - 即执行该字符串中的操作码。
答案 2 :(得分:4)
void(*)()
表示“指向不带参数的void函数的指针。”这条线
(*(void(*)()) shellcode)();
将shellcode
转换为这样的函数指针,取消引用指针(实际上不需要),然后调用该函数。
答案 3 :(得分:3)
这是一个函数指针。类型说明符匹配声明;所以函数void f()
的类型为void()
;并且指向函数void (*pf)()
的指针的类型为void(*)()
。
请注意,与函数声明一样,它在C和C ++中的含义略有不同。在C中,空括号表示它具有未指定数量的参数,而在C ++中它表示它没有参数。但是,这不会影响代码的含义。
此代码将数组重新解释为函数并尝试调用它。据推测,该阵列包含用于打印消息或格式化硬盘驱动器等的机器代码。在大多数现代平台上,这将导致保护错误,因为静态数据(希望)默认情况下不可执行。