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

3
在Linux中,有没有可能以某种方式更改另一个进程的内存映射?与之相反的是,仅能通过在进程本身中运行的代码调用mmap来控制它。
我提出这个问题的原因是,我想能够构建一个具有非常自定义的内存映射的进程,而且不能使用共享库甚至不使用vDSO,我不知道如何在进程内部做到这一点,除非基本上编写自己的libc以处理系统调用等。(即使我链接了静态libc,它是否会尝试使用vDSO?)

我怀疑这可能可以通过ptrace实现,但我不知道具体细节。 - nneonneo
@nneonneo:如果是这样的话,那么“ptrace”手册肯定没有明确说明。 :) - Dolda2000
其中最愚蠢(但足够)的方法之一是使用ptrace暂停目标程序,修改接下来的几条指令以包含所需的mmap调用,然后恢复它。完成mmap处理后,您会取消修补目标并还原指令指针。这很邪恶,但它能够奏效(此页面介绍了类似技术的详细信息)。 - nneonneo
是的,我考虑过类似的方法,但我认为它不会很好地工作,因为我事先不知道需要映射到哪个地址以避免与目标内存布局冲突。此外,我还不知道如何控制vDSO的映射方式和位置,尽管我正在探索这方面的内容。 - Dolda2000
@nneonneo,难道不应该使用gdb吗? - glglgl
显示剩余2条评论
1个回答

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 机制(如套接字)接收命令并相应地操作映射。


很抱歉,但我必须承认我不明白这如何回答问题。 - Dolda2000
我理解你的问题是如何构建一个内存映射,然后将其传递给某个现有程序。也许你应该说明一下你正在做什么,以及你期望得到什么样的答案。 - Grapsus
好的,直接的问题是是否可以操纵另一个进程的内存布局。 :) 更通用的问题似乎是你试图回答的,即完全任意地构造进程的内存空间;然而,就我所看到的,你的答案只涉及添加映射。我必须承认我不太明白如何重新表述问题以使其更清晰。 - Dolda2000
@Dolda2000 好的,所以我的回答并不完全离题,就像你在第一条评论中说的那样。我向你展示了如何添加映射。我的例子可以很容易地扩展到在程序内部透明地注入“内存管理器”线程。该线程将通过 IPC 机制(如套接字)接收命令,并相应地操作映射。 - Grapsus
当然可以,但我希望在问题中已经清楚地表明了为什么我想避免从进程内部控制内存映射的想法。 :) - Dolda2000

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接