c++ - mmap 系统调用失败并显示 errno 14
问题描述
我试图在另一个进程上使用 MMAP 进行系统调用注入,但它失败了。我注意到系统调用正常执行,所以问题应该是别的。我决定直接通过目标程序运行系统调用,以使其更易于理解。不出所料,它也不起作用,我真的不知道为什么:
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/syscall.h>
#include <sys/errno.h>
int main()
{
void* addr = 0;
size_t len = sysconf(_SC_PAGE_SIZE);
int prot = PROT_EXEC | PROT_READ | PROT_WRITE;
int flags = MAP_PRIVATE | MAP_ANON;
int fd = -1;
off_t offset = 0;
void* alloc0 = mmap(addr, len, prot, flags, fd, offset); //this works
void* alloc1 = syscall(__NR_mmap, addr, len, prot, flags, fd, offset); //this doesn't work
printf("Alloc0: %p\n", alloc0);
printf("Alloc1: %p\n", alloc1);
printf("Errno: %i\n", errno);
return 0;
}
输出:
Alloc0: 0xf7fac000
Alloc1: 0xffffffff
Errno: 14
为什么正常的 mmap 可以工作,而具有相同参数的 mmap 系统调用不能工作?
我正在运行 Manjaro,并且该程序已使用 32 位 GCC 编译。此外,当我以 64 位编译它时,它工作得很好,没有错误。有任何想法吗?
解决方案
The legacy __NR_mmap
syscall on 32-bit (at least 32-bit x86 anyway) does not have that signature. It takes a single argument that's a pointer to a struct mmap_arg_struct32
; see https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/x86/kernel/sys_ia32.c?id=v5.9#n214. This syscall is deprecated since the mid to late 90s, and should not be used. Error number 14 is EFAULT
and is reflecting that your first argument is not a valid pointer to such a struct.
The modern replacement is __NR_mmap2
and it takes arguments similar to the mmap
function, except that offset
is a 32-bit count of 4k units, rather than a direct offset. This allows addressing offsets up to 2^44 in magnitude.
推荐阅读
- python - 如何找到决策树分类的特征名称?
- javascript - 从模块导入多个条目并分配给 JavaScript 中的某个别名
- r - R - 返回找到第一个给定值的行的列名
- python - 无法在兄弟子文件夹之间导入 python 文件
- java - QueryDSL 和枚举内部字段持续存在
- java - log4j2 - 需要帮助设置 JMS Appender 以使用 IBM MQ 系列
- c# - 如何在 EF Core 中创建外键关系?
- ios - Ionic Xcode 无法打开文件(目标应用程序)
- reactjs - 如何在 React 中访问组件之外的 Redux 存储
- javascript - 在特定的反应地图项上应用样式