C++ mProtect 用于读取、写入和执行

c++ mprotect for read, write and execute

本文关键字:执行 mProtect 用于 读取 C++      更新时间:2023-10-16

作为我正在从事的项目的一部分,我想分配一些内存,将操作码写入该内存,然后call它。届时,代码将跳转到我分配的内存中,运行操作码并使用操作码ret返回到上一个位置。

我的代码在Linux上运行,不需要支持Windows。

我尝试将mprotect与标志一起使用PROT_READ | PROT_WRITE | PROT_EXEC但是我收到"权限被拒绝"错误。 我需要在此内存上的写入和执行权限。

我怎样才能实现我正在尝试的目标?为什么我会收到"权限被拒绝"?

分配的内存是使用aligned_alloc分配的,因此它将与 4KB(页面大小(对齐。

对我来说,PaX/GrSecurity 似乎很有效:

PaX项目的目标是研究各种防御机制 防止利用软件错误,使攻击者任意 对受攻击任务的地址空间的读/写访问权限。这类错误 包含各种形式的缓冲区溢出错误(无论是堆栈 或基于堆(,用户提供的格式字符串错误等。

可以通过以下任一方式将代码引入任务的地址空间 创建可执行映射或修改已存在的映射 可写/可执行映射。 第二种方法可以通过不允许 创建可写/可执行映射

尝试使用实用程序paxctl禁用程序二进制文件的内存保护机制。

我找到了一个解决方案,很高兴了解会发生什么。希望你会喜欢。

在测试它时,您可以看到,如果您分配一个"大"内存块(如1MBmprotect管理添加执行权限。使用二叉搜索,您可以发现最佳点在128KB.Glibc的malloc以一种有趣的方式工作,你应该阅读,但很快,它会提前分配内存,并在你要求时给你一些。如果内存不足,它会分配更多,依此类推。但是在某些大小下,它不会从自己的池中为您提供内存。你要求一个足够大的缓冲区,让他专门为你分配一个。此阈值为 128KB,由源代码中的DEFAULT_MMAP_THRESHOLD定义。

默认内存由位于不同内存段中的 glibc.o 分配,并在运行时加载。因此,您的库无权更改该内存保护和添加PERM_EXEC。但是,当您请求大内存并且malloc为您分配新内存时,您的库拥有该内存,因此您可以根据需要更改其权限。

更多详细信息以及如何解决小内存量:

那么 GCC 如何为您分配内存呢? 使用mmap- http://man7.org/linux/man-pages/man2/mmap.2.html

#include <sys/mman.h>
void *mmap(void *addr, size_t length, int prot, int flags,
int fd, off_t offset);
int munmap(void *addr, size_t length);

mmap新的内存段中分配内存。If addr is NULL, then the kernel chooses the (page-aligned) address at which to create the mapping.因此,我们可以使用此函数分配内存。length必须是页面大小(4096(的乘法,这对于小内存量来说可能是相当浪费的。如果fd-1则内存充满零。

使用这种方法,我们可以根据需要分配具有保护的内存,在这种情况下,可以使用执行权限。