函数类型转换后执行的变量中定义的代码在哪里?

问题描述 投票:0回答:1

以下代码的行为令我感到困惑 (SMP Debian 4.19.260-1 (2022-09-29) x86_64 GNU/Linux):

#include <stdio.h>
const char
shellcode[]="\xb8\×01\×00\x00\x00\×48\xbe\×48\×65\×6c\x6c\×6f\×00\×00\×00\×56\×48\x89\xe6\xba\x05\x00\x00\x00\x0f\x05\xb8\x3c\x00\x00\x00\x0f\x05";
int main(){
    (*(void (*) ()) shellcode)();
    return 0;
}

当我通过调试器执行程序时,我看到在将数组转换为函数之后执行的代码位于人们期望看到它的位置,即在初始化的全局区域中(因为它是这样定义的)。换句话说,代码在进程地址空间中非常低,绝对不在堆栈中。

然而,要在不接收 SIGSEGV 的情况下实际运行代码,必须使用可执行堆栈选项 -z execstack 对其进行编译。如果代码不在堆栈中,为什么会发生这种情况? 预先感谢您的建议。 佛朗哥

linux gdb stack typecasting-operator
1个回答
0
投票
  1. 您粘贴的代码无效:
 shellcode[]="\xb8\<U+00D7>01\<U+00D7>00...

这些应该是

\x
,而不是
.

  1. 在我的系统上,使用
    gcc t.c -Wl,-z,execstack
    编译它仍然会崩溃。这是因为
    const char ...
    被放入
    .rodata
    部分,该部分进入只读段(不可执行)。

您应该 a) 显示您使用的确切编译/链接命令,以及 b) 显示您使用的编译器版本以获得更详尽的答案。

同时查看

readelf -Wl ./a.out
以查看 segment 权限是什么——您的
.rodata
很可能最终处于没有执行权限的段中。

© www.soinside.com 2019 - 2024. All rights reserved.