首页 > 解决方案 > Ptrace 允许写入可执行程序段,但 process_vm_writev 不允许

问题描述

在尝试用 C 语言在 Linux 上编辑正在运行的进程的操作码时,我发现我不能用 PID 来编辑程序操作码process_vm_writev,但是使用ptrace并且pwrite我可以做到。process_vm_writev返回 -1 并errno说“地址错误”。但是当我使用具有相同地址的 ptrace 时,它​​会成功。我以root身份运行程序。它是 GNU/Linux 的问题吗?我应该在 GitHub 上打开一个问题吗?代码process_vm_writev(不包括简短):

ssize_t write_pmem(pid_t pid, off_t addr, void* value, size_t size) {
    struct iovec local[1];
    local[0].iov_base = value;
    local[0].iov_len = size;
    struct iovec remote[1];
    remote[0].iov_base = (void*)addr;
    remote[0].iov_len = size;

    return process_vm_writev(pid, local, 1, remote, 1, 0);
}

int main() {
    pid_t pid;
    off_t opcode_ptr = 0x45B5A7;

    printf("PID: ");
    scanf("%d", &pid);

    char nops[5] = {0x90, 0x90, 0x90, 0x90, 0x90};
    ssize_t res = write_pmem(pid, opcode_ptr, &nops, sizeof(nops));

    printf("%ld\n%s", res, strerror(errno));
    /* and it prints:
       -1
       Bad address */
    return 0;
}

/proc/PID/maps说那0x45B5A700406000-004f0000 r-xp 00006000针对那个过程的(没有写权限),但我认为它对于根目录仍然是可写的。

我想使用新的 process_vm Linux API,所以我想修复该代码。有任何想法吗?

标签: clinuxlow-levelptrace

解决方案


推荐阅读