帮我理解这个C代码(*(void(*)())scode)()

sha*_*kuo 2 c

资料来源:http://milw0rm.org/papers/145

#include <stdio.h>
#include <stdlib.h>

int main()
{
 char scode[]="\x31\xc0\xb0\x01\x31\xdb\xcd\x80";
 (*(void(*) ()) scode) ();
}
Run Code Online (Sandbox Code Playgroud)

这篇论文是关于Linux平台上的shellcode的教程,但它没有解释下面的语句如何(*(void(*) ()) scode) ();起作用.我正在使用"The C Language Programming Reference,2 by Brian.W.Kernighan,Dennis.M.Ritchie"来查找答案,但没有找到答案.可能有人可以指向正确的方向,也许是一个网站,另一个C参考书,在那里我可以找到答案.

Dus*_*etz 14

它的机器代码(编译的汇编指令)scode然后它转换为可调用的void函数指针并调用它. GMan展示了一种等效,更清晰的方法:

typedef void(*void_function)(void);
int main()
{
  char scode[]="\x31\xc0\xb0\x01\x31\xdb\xcd\x80";
  void_function f = (void_function)scode;
  f(); //or (*f)();
}
Run Code Online (Sandbox Code Playgroud)

scode包含x86机器代码,可拆解成(感谢Michael Berg)

31 c0        xor    %eax,%eax
b0 01        mov    $0x1,%al
31 db        xor    %ebx,%ebx
cd 80        int    $0x80
Run Code Online (Sandbox Code Playgroud)

这是Linux中的系统调用代码(中断0x80).根据系统调用表,这是使用参数0(in )调用sys_exit()系统call().这会导致进程立即退出,就像调用它一样.eax=1ebx_exit(0)

Jonathan Leffler指出,这最常用于调用shellcode,"一小段代码用作利用软件漏洞的有效载荷." 因此,现代操作系统采取措施来防止这种情况.

如果堆栈是不可执行的,则此代码将失败.shell代码被加载到堆栈中的局部变量中,然后我们跳转到该位置.如果堆栈是不可执行的,那么一旦CPU尝试执行代码就会发生某种CPU故障,并且控制将转移到内核的中断处理程序中.然后内核将以异常方式终止进程.堆栈可能不可执行的一种情况是,如果您在支持物理地址扩展的CPU上运行,并且您在页表中设置了NX(不可执行)位.

某些CPU上可能还存在指令缓存问题 - 如果指令缓存尚未刷新,则CPU可能会读取过时数据(而不是我们显式加载到堆栈中的shell代码)并开始执行随机指令.


Mic*_*erg 7

在C:

(some_type) some_var
Run Code Online (Sandbox Code Playgroud)

将some_var强制转换为some_type类型.

在您的代码示例中,"void(*)()"是some_type,并且是函数指针的签名,它不带任何参数并且不返回任何内容."(void(*)())scode"casts scode是一个函数指针."(*(void(*)())scode)"取消引用该函数指针.final()调用scode中定义的函数.

并且scode中的字节反汇编到以下i386程序集:

   31 c0        xor    %eax,%eax
   b0 01        mov    $0x1,%al
   31 db        xor    %ebx,%ebx
   cd 80        int    $0x80
Run Code Online (Sandbox Code Playgroud)


Nic*_*ord 6

这段代码的作用是分配一些机器代码(scode中的字节)然后它将该代码的地址转换为类型的函数指针void function ()然后调用它.

在C/C++中,表达了该函数的类型定义:

typedef void (* basicFunctionPtr) (void);
Run Code Online (Sandbox Code Playgroud)


GMa*_*ckG 5

一个typedef帮助:

// function that takes and returns nothing
typedef void(*generic_function)(void);

// cast to function
generic_function f = (generic_function)scode;

// call
(*f)();

// same thing written differently:
// call
f();
Run Code Online (Sandbox Code Playgroud)