You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Linux:将被调试进程内存映射到调试器内存空间

实现方法

核心思路

/proc/<pid>/mem确实不支持mmap操作,因为procfs是虚拟文件系统,无法提供内存映射所需的物理页面对应关系。替代方案是:先创建本地匿名内存映射,再通过ptrace()将被调试进程的目标内存区域数据同步到这个映射区,后续直接读写本地映射即可,按需同步回被调试进程。

具体步骤

  1. 解析/proc/<pid>/maps获取目标区域信息
    读取该文件提取目标内存块的关键参数:起始虚拟地址、结束地址、权限。比如一条典型的映射条目:

    55f8d7a00000-55f8d7a22000 r--p 00000000 103:02 168933 /usr/bin/bash
    

    计算区域长度:length = 结束地址 - 起始地址,记录起始地址target_addr。

  2. 创建匹配权限的匿名映射
    用mmap()创建与目标区域权限、大小一致的本地匿名映射:

    void *local_map = mmap(NULL, length, PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
    if (local_map == MAP_FAILED) {
        perror("mmap failed");
        exit(EXIT_FAILURE);
    }
    

    权限需和目标区域对应,比如目标是rw-p就用PROT_READ | PROT_WRITE。

  3. 通过ptrace()同步远程内存到本地
    用PTRACE_READV批量读取比逐个PTRACE_PEEKDATA效率更高。先构造iovec结构体分别指向本地映射和远程目标地址:

    struct iovec local_iov = {.iov_base = local_map, .iov_len = length};
    struct iovec remote_iov = {.iov_base = (void *)target_addr, .iov_len = length};
    
    // 确保被调试进程处于停止状态(比如已通过PTRACE_ATTACH附加)
    if (ptrace(PTRACE_READV, pid, &remote_iov, &local_iov) == -1) {
        perror("ptrace READV failed");
        exit(EXIT_FAILURE);
    }
    
  4. 直接读写本地映射区
    现在可以像操作普通内存一样读写local_map,无需再调用系统访问被调试进程内存。

  5. (可选)同步本地修改回被调试进程
    如果需要将修改内容写回,用PTRACE_WRITEV反向操作:

    if (ptrace(PTRACE_WRITEV, pid, &local_iov, &remote_iov) == -1) {
        perror("ptrace WRITEV failed");
        exit(EXIT_FAILURE);
    }
    

注意事项

  • 操作前需确保拥有足够权限(root或同UID),且被调试进程处于可ptrace的状态。
  • 若目标内存区域动态变化(如被换出、权限变更),需重新执行同步步骤。
  • 操作完成后可通过PTRACE_DETACH解除对被调试进程的附加。

内容的提问来源于stack exchange,提问作者tuxifan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 16:18:21