繁体   English   中英

代码中void(*)()是什么意思

[英]What does void(*)() mean in code

我今天在一些 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;
}

它是对函数指针的强制转换(没有返回结果,也没有参数)。 我更喜欢使用typedef来定义此类函数的签名:

 typedef void plainsig_t(void);

然后简单地编码

 (*(plainsig_t*)shellcode) ();

对于函数指针,您无需取消引用它们,因此仅需编写代码即可:

 ((plainsig_t*) shellcode) ();

它基本上会调用其机器代码位于shellcode存储区中的函数。

顺便说一句,这不是严格可移植的C。原则上,不能保证可以将数据指针转换为函数指针。 (在某些奇怪的处理器上,例如嵌入式微控制器,DSP,1970年代的计算机上,代码和数据位于不同的地址空间中,或具有不同的指针大小,等等。) 但是大多数常见的处理器和ABI(x86-64 / Linux,ARM / Android等)具有用于代码和数据的相同地址空间,并接受将函数指针转换为数据指针,反之亦然。

这是C和C ++不同的地方。

在C语言中,它表示指向函数的指针,该函数返回void并接受未指定类型的未指定数量的参数。

在C ++中,它表示指向返回空值且不带参数的函数的指针。

整个表达式都使用shellcode的地址,将其转换为指向函数类型的指针,然后调用该函数-即,执行该字符串中的操作码。

void(*)()意思是“指向不带参数的void函数的指针。” 线

(*(void(*)()) shellcode)();

是将shellcode强制转换为此类函数指针,然后取消对该指针的引用(实际上不是必需的),然后调用该函数。

这是一个函数指针。 类型说明符匹配声明; 因此,函数void f()类型为void() 并且指向函数void (*pf)()的指针的类型为void(*)()

注意,与函数声明一样,它在C和C ++中的含义稍有不同。 在C中,空括号表示它具有未指定数量的参数,而在C ++中,表示没有参数。 但是,这不会影响代码的含义。

此代码将数组重新解释为函数,然后尝试调用它。 据推测,该数组包含用于打印消息,格式化硬盘或其他内容的机器代码。 在大多数现代平台上,这将导致保护错误,因为默认情况下(希望)静态数据不可执行。

在 C 中,变量声明为int foo; , 声明一个 function 我们使用int foo( ); 这意味着 function 的返回类型是 int。 我们使用*foo来声明一个指针。

在表达式(*(void(*)())0)()中我们可以看到

  1. 假设变量fp是一个 function 指针,我们可以使用(*fp)( ); 调用function,因为fp是一个function指针,而*fp是指针指向的function,所以(*fp)( ); 可拨打function。

  2. 假设fp是一个非返回值类型的指针,那么调用它的方式就是void (*fp)( ) ,那么fp变量的类型就是void (*)( )

  3. 如果我们要将此类型转换为常量shellcode ,那么我们使用( void (*)() ) shellcode

  4. 现在 shellcode 已转换为类型,为了调用我们使用的 shellcode

    ( ( void (*)() ) shellcode )();


注意:我们可以用typedef来代替上面表达式的类型名

例如: typedef void (*ff)( ); 因此,调用function的方式可以写成:

(*(ff) shellcode ) ( );

来自: https://www.codetd.com/en/article/14043929

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM