【发布时间】:2023-04-04 03:45:01
【问题描述】:
我在 linux 系统(准确地说是 centos 5.4)上的 C 程序中在运行时生成 x86-64 代码。
我将我的字节码生成到一个全局数组中,如下所示
char program[1024 * 1024] __attribute__((aligned (16)));
然后通过函数指针调用它。
我的问题是,当我像这样编译程序时
gcc -std=gnu99 parse.c -o parse -lm
我得到一个 SIGSEGV,我推测这是由于 bss 部分没有被设置为可执行文件,如 pmap 所示
0000000000601000 4K rw--- /data/work/tmp/parse
0000000000602000 1024K rw--- [ anon ]
当我这样编译时,(empty.s 是一个零长度文件)
gcc -std=gnu99 parse.c empty.s -o parse -lm
在运行时,bss 部分神奇地设置了执行位,一切正常。
0000000000601000 4K rwx-- /data/work/tmp/parse
0000000000602000 1024K rwx-- [ anon ]
那么,如何在 ELF 中设置这些标志?是否有可靠、正确的方法来获取具有 rwx 权限的 bss 部分?
更多细节 - 软件版本
gcc 版本 4.1.2 20080704 (Red Hat 4.1.2-48)
Linux 2.6.18-164.15.1.el5 x86_64 GNU/Linux
谢谢
更新 - 起初我以为我无法按照 caf 的建议使用 mmap 来解决这个问题,因为 mmap 给我返回的页面太远了(我想跳转到具有相对地址的附近代码)。事实证明,您可以要求 mmap 为您处理这个问题,就像这样 - MAP_32BIT 会在前 2GB 中为您返回一个页面。
char* program = mmap(0, 1024 * 1024, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_32BIT | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
【问题讨论】:
-
你知道为什么 .bss 设置了执行位吗?
标签: c linux gcc assembly x86-64