c - 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
说那0x45B5A7
是00406000-004f0000 r-xp 00006000
针对那个过程的(没有写权限),但我认为它对于根目录仍然是可写的。
我想使用新的 process_vm Linux API,所以我想修复该代码。有任何想法吗?
解决方案
推荐阅读
- sql-server - Fitbit 数据导出 - 创建数据仓库
- python - 使用pyhdf时如何处理py2和py3中不同类型的np.array(list)?
- java - 每个用户具有单个实例的 Java 应用程序
- javascript - 将鼠标悬停在图像上时如何显示虚拟箭头
- flutter - Gradient in SliverAppBar (Flutter)?
- ruby-on-rails - Foundation 6 top-bar dropdown won't close
- curl - building netcdf on linux
- android - 第一次单击共享元素时,我的 SharedElement 过渡会闪烁
- javascript - 如何在本机反应中将事件侦听器添加到状态
- android - 如何将结果从 JavascriptInterface 传输到 OnCreate?