C - 如何 (*(void (*)()) 代码); 运行 在没有任何调用的 C 程序中

C - how does (*(void (*)()) code); run in a C program without any invocation

To 运行 C 程序中的任意汇编十六进制指令通常需要将数据转换为函数指针,然后调用此类指针。

常见用法

int main(){    
    void (*ret)() = (void(*)())code;
    ret();
    return 0;
}

然而,我也 运行 通过另一种方式来完成同样的任务

问题案例

int main() {
    (*(void (*)()) code);
    return 0;
}

谁能帮忙解释一下:

  1. 两种情况的区别
  2. 为什么第二种情况没有任何调用就可以工作

如果在第二种情况的脚本中实际调用十六进制代码,很难在调试器(如 GDB)中跟踪十六进制指令代码,就会出现问题。

编辑

测试的程序是用gcc编译的,选项为:-fno-stack-protector -z exexcstack

机器测试和 gcc 版本:

gcc version 7.3.0 (Ubuntu 7.3.0-27ubuntu1~18.04)

第二段代码不行。 未使用的 deref 是空操作。它相当于一个空函数。 如果你想避免变量使用 ((void (*)())code)().

示例:

extern char *code;
void run()
{
    void (*ret)() = (void(*)())code;
    ret();
}
void run0()
{
    (*(void (*)()) code);
}
void empty()
{
}
void novar()
{
    ((void (*)())code)();
}

示例的反汇编(x86_64):

ex.o:     file format elf64-x86-64


Disassembly of section .text:

0000000000000000 <run>:
   0:   55                      push   %rbp
   1:   48 89 e5                mov    %rsp,%rbp
   4:   48 83 ec 10             sub    [=11=]x10,%rsp
   8:   48 8b 05 00 00 00 00    mov    0x0(%rip),%rax        # f <run+0xf>
   f:   48 89 45 f8             mov    %rax,-0x8(%rbp)
  13:   48 8b 55 f8             mov    -0x8(%rbp),%rdx
  17:   b8 00 00 00 00          mov    [=11=]x0,%eax
  1c:   ff d2                   callq  *%rdx
  1e:   90                      nop
  1f:   c9                      leaveq 
  20:   c3                      retq   

0000000000000021 <run0>:
  21:   55                      push   %rbp
  22:   48 89 e5                mov    %rsp,%rbp
  25:   90                      nop
  26:   5d                      pop    %rbp
  27:   c3                      retq   

0000000000000028 <empty>:
  28:   55                      push   %rbp
  29:   48 89 e5                mov    %rsp,%rbp
  2c:   90                      nop
  2d:   5d                      pop    %rbp
  2e:   c3                      retq   

000000000000002f <novar>:
  2f:   55                      push   %rbp
  30:   48 89 e5                mov    %rsp,%rbp
  33:   48 8b 05 00 00 00 00    mov    0x0(%rip),%rax        # 3a <novar+0xb>
  3a:   48 89 c2                mov    %rax,%rdx
  3d:   b8 00 00 00 00          mov    [=11=]x0,%eax
  42:   ff d2                   callq  *%rdx
  44:   90                      nop
  45:   5d                      pop    %rbp
  46:   c3                      retq   

https://gcc.godbolt.org/z/lEo5ga