控制另一个进程的内存映射

时间:2014-05-12 19:38:04

标签: linux process mmap virtual-memory

是否有可能以某种方式更改Linux中另一个进程的内存映射?相反,也就是说,只能通过在调用mmap的进程中运行的代码来控制它。

我之所以问的原因是因为我希望能够使用非常自定义的内存映射构建流程,而且无法使用共享库甚至vDSO,我也不会这样做。 ; t看到在进程本身内做任何方式,基本上不涉及编写我自己的libc来处理系统调用等。 (即使我要静态链接libc,它是否会尝试使用vDSO?)

1 个答案:

答案 0 :(得分:0)

mmap映射内存由fork保留,但被来自exec系列的系统调用擦除,因此经典序列fork无法实现此设置然后是exec

一个简单的解决方案是使用LD_PRELOAD钩子。我们将此代码放在add_mmap.c

#include <sys/mman.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

void add_mmap(void) __attribute__((constructor));

void add_mmap(void)
{
    int fd;
    void *addr;

    printf("calling mmap() before main...\n");
    fd = open("/etc/passwd", O_RDONLY);
    printf("fd=%d\n", fd);
    /* map the first 100 bytes of the file to an address chosen by the kernel */
    addr = mmap(0, 100, PROT_READ, MAP_SHARED, fd, 0);
    printf("addr=%llx\n", (long long unsigned)addr);
}

然后,将其构建为动态库:

gcc -Wall -g -fPIC -shared -o add_mmap.so add_mmap.c

最后用它运行一些现有的程序:

$ LD_PRELOAD=./add_mmap.so /bin/cat 
calling mmap() before main...
fd=3
addr=7fe4916f8000

我们可以在cat运行之前检查映射是否已设置并保留:

$ cat /proc/27967/maps
...
7f2f7f2d0000-7f2f7f2d1000 r--s 00000000 09:00 1056387                    /etc/passwd
...

修改

我只在这里展示如何在程序启动之前添加内存映射,但是我的示例可以很容易地扩展到在程序中透明地注入“内存管理器”线程。该线程将通过类似套接字的IPC机制接收订单并相应地操作映射。