在C中将缓冲区作为函数调用?

时间:2019-01-24 07:53:56

标签: c pointers

char buf[sizeof(shellcode)];
strcpy(buf, shellcode);
((void(*)())buf)();

我很难理解第三行的语法,我认为它使缓冲区成为函数?

1 个答案:

答案 0 :(得分:3)

您对第三行是正确的。它使用buf,将其衰减为指针,然后将该指针强制转换为函数指针。然后调用该函数。之所以起作用,是因为void(*)()的意思是“指向不接受任何参数并返回void的函数的指针”,并将其包装在括号中会将其转换为强制类型转换。现在,您有一个指向函数的指针,就可以像正常的函数名称一样调用它。

C标准不允许这样做,但是基于编译器的工作方式,这可能意味着它将buf的地址视为内存中函数的地址,并尝试调用该函数。通常这是行不通的,因为OS会告诉CPU将内存buf标记为不可执行,因此,当您假装它是一个函数时,CPU会抛出错误。我们假设操作系统没有执行此操作,或者您有足够老的CPU不支持该功能。

您没有向我们显示shellcode的内容。由于计算机中的所有内容都是一个字节序列,包括计算机运行的已编译二进制代码,因此shellcode可能包含可执行二进制代码。如果确实如此,那么这将导致该代码开始运行。

例如,如果您编译

void mycode()
{
    puts("Hello, world!");
}

然后可以从生成的目标文件中提取功能mycode的内容。如果将这些内容放入shellcode中,那么问题中的代码将(假设编译器将指向函数的指针和指向数据的指针相同,并且操作系统或CPU不支持noexec内存) )将Hello, world!打印到屏幕上。