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

xuo3flqw  于 2023-03-07  发布在  Linux
关注(0)|答案(1)|浏览(107)

以下代码(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编译它。如果代码不在堆栈上,为什么会发生这种情况?

    • 更新日期:**

我使用了以下命令:

$ gcc testshellcode.c -o testshellcode
$ ./testshellcode
Segmentation fault

$ gcc -z execstack testshellcode.c -o testshellcode
$ ./testshellcode
Hello

我使用的是gcc (Debian 8.3.0-6) 8.3.0

    • 找到的解决方案:execstack标志使内存中的所有**页都可执行,而不仅仅是堆栈中的页。请参阅:

Why is execstack required to execute code on the heap?
Exactly what cases does the gcc execstack flag allow and how does it enforce it?

bkkx9g8r

bkkx9g8r1#

1.您粘贴的代码无效:

shellcode[]="\xb8\<U+00D7>01\<U+00D7>00...

这些应该是\x,而不是
1.在我的系统上,用gcc t.c -Wl,-z,execstack编译这个代码仍然会崩溃,这是因为const char ...被放到了.rodata节中,而.rodata节是一个只读段(不可执行)。
您应该a)显示您使用的确切compile / link命令,B)显示您使用的编译器版本,以获得更全面的答案。
还可以查看一下readelf -Wl ./a.out,看看 segment 权限是什么--您的.rodata很可能最终处于没有执行权限的段中。

相关问题