mmap syscall失败,错误号为14

问题描述

我试图在另一个进程上使用MMAP进行系统调用注入,但失败了。我注意到syscall正在正确执行,因此问题应该是其他原因。我决定直接通过目标程序运行syscall,以使其更易于理解。毫不奇怪,它也不起作用,我也不知道为什么:

#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,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 syscall无法正常工作?
我正在运行Manjaro,并且该程序已使用GCC在32位上进行了编译。另外,当我用64位编译它时,它工作得很好,没有错误。有什么想法吗?

解决方法

32位(无论如何至少为32位x86)上的旧式__NR_mmap系统调用没有该签名。它只接受一个指向struct mmap_arg_struct32的指针的参数。参见https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/x86/kernel/sys_ia32.c?id=v5.9#n214。此系统调用自90年代中期以来不推荐使用,不应使用。错误编号14为EFAULT,反映出您的第一个参数不是指向此类结构的有效指针。

现代替换是__NR_mmap2,它采用类似于mmap函数的参数,除了offset是4k单位的32位计数,而不是直接偏移量。这样可以处理最大2 ^ 44的偏移量。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...