char buf[sizeof(shellcode)];
strcpy(buf, shellcode);
((void(*)())buf)();
我很难理解第三行的语法,我认为它正在使缓冲区成为一个函数?
最佳答案
你对第三行是正确的。它获取 buf
,将其衰减为一个指针,然后将该指针转换为指向函数的指针。然后它调用该函数。这是可行的,因为 void(*)()
表示“指向不接受任何参数并返回 void
的函数的指针”,并将其括在括号中会将其转换为强制转换。您现在有一个指向函数的指针,您可以像调用常规函数名称一样调用它。
C 标准不允许这样做,但根据编译器的工作方式,可能意味着它将 buf
的地址视为内存中函数的地址并尝试调用该函数。通常这是行不通的,因为操作系统会告诉 CPU 将 buf
所在的内存区域标记为不可执行,因此当您试图假装它是一个函数时,CPU 会抛出错误;让我们假设操作系统不执行此操作,或者您的 CPU 足够旧,它不支持此操作。
你没有向我们展示 shellcode
的内容。由于计算机中的所有内容都只是一个字节序列,包括您的计算机运行的已编译二进制代码,shellcode
可能包含可执行二进制代码。如果是,则会导致该代码开始运行。
例如,如果你编译
void mycode()
{
puts("Hello, world!");
}
然后您可以从生成的目标文件中提取函数 mycode
的内容。如果您将这些内容放入 shellcode
,那么您问题中的代码将(假设编译器将函数指针和数据指针视为相同,并且操作系统或 CPU 不支持 noexec 内存)打印 Hello, world!
到屏幕。
关于在 C 中将缓冲区作为函数调用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54341743/