在使用C语言编辑Linux上正在运行的进程操作码时,我发现我无法通过PID使用process_vm_writev
来编辑程序操作码,但是使用ptrace
和pwrite
可以实现。 process_vm_writev
返回-1,errno
显示“Bad address”。但是当我使用相同地址的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
显示该进程中 0x45B5A7
在内存中的区域是 00406000-004f0000 r-xp 00006000
(没有写入权限),但我认为 root 用户仍然可以进行写操作。
我想使用新的 process_vm Linux API,所以我想修复这段代码。有什么想法吗?
PTRACE_MODE_ATTACH_REALCREDS
检查来管理;请参见 ptrace(2)。” 手册中的示例没有使用ptrace
连接到该 PID,但如果您想写入只读内存,则可能需要这样做。也许我误解了它,它只是在谈论是否被允许写入远程内存,而不是页面权限。 - Peter Cordes