gpt4 book ai didi

c - 如何在 C 中将一段内存标记为可执行?

转载 作者:太空宇宙 更新时间:2023-11-04 00:27:57 25 4
gpt4 key购买 nike

最近在研究一些JIT编译器。据我所知,JIT 是一种将一些脚本语言代码即时(在执行之前)编译为 native 代码的技术。当我想象这样一个编译器的内部时,我发现生成的 native 代码所在的位置必须有一段动态分配的缓冲区。但是我们需要一种方法来从保存数据的缓冲区中开始运行代码。我的意思是,您不能只是将一些代码放入 char[] 中,然后因为安全隐患而跳转到执行,操作系统必须阻止您这样做。必须有某种方法将缓冲区标记为可执行。考虑以下天真的方法:

#include <stdlib.h>

void *jit_some_native_code(void) {
void *code_segment = malloc(1024);
/*
* bla bla bla...
* Generate code into this code_segment.
*/

return code_segment;
}

int main(void) {
void *code = jit_some_native_code();
/*
* How can I start executing instruction in code?
*/

typedef void (*func_ptr_t)(void);

/*
* This won't work. OS bans you doing so.
*/
((func_ptr_t)code)();

}

在 Ubuntu 上,代码将运行但将以状态代码 26 退出。鉴于 C 的类型不安全性质,代码可以编译,但对于 C++,编译器只会阻止您。这是否意味着 JIT 必须绕过编译器并设置可执行标志?

编辑:除了mprotect,如果使用mmap,还可以指定一个权限给要映射的页面:

   PROT_EXEC  Pages may be executed.
PROT_READ Pages may be read.
PROT_WRITE Pages may be written.
PROT_NONE Pages may not be accessed.

因此该页面将具有可执行权限。

最佳答案

如果你想在堆中创建一个可执行区域,你可以使用mprotect .

int main() {
typedef void (*func_t)(void);
void *code = &some_jit_func;
int pagesize = getpagesize();
mprotect(code, pagesize,PROT_EXEC);
((func_t)code)();
}

您还可以将标志与 PROT_READ/PROT_WRITE 或

关于c - 如何在 C 中将一段内存标记为可执行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57459867/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com