我正在玩linux中的ptrace。我试图使用/ proc / pid / mem接口编写跟踪进程的内存。
我用来完成这项任务的功能是:
void write_proc(pid_t child, unsigned long int addr) {
char mem_file_name[100];
char buf[10]="hope";
int mem_fd;
memset( (void*)mem_file_name, 0, 100);
memset( (void *)buf, 0, 10);
sprintf(mem_file_name, "/proc/%d/mem", child);
mem_fd = open(mem_file_name, O_RDONLY);
lseek(mem_fd, addr , SEEK_SET);
if (write(mem_fd, buf, 5) < 0 )
perror("Writing");
return;
}
但我总是得到错误:写:错误的文件描述符。
是否可以使用此方法编写跟踪过程?
答案 0 :(得分:4)
您正在以只读模式(O_RDONLY
)打开文件。我建议您再次尝试O_RDWR
:
mem_fd = open(mem_file_name, O_RDWR);
然而,从man proc
开始,不清楚这是否有效:
/proc/[pid]/mem This file can be used to access the pages of a process's memory through open(2), read(2), and lseek(2).
编辑:
我也很好奇,所以我直接使用ptrace()
整理了这个例子:
#include <sys/ptrace.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#define SHOW(call) ({ int _ret = (int)(call); printf("%s -> %d\n", #call, _ret); if (_ret < 0) { perror(NULL); }})
char changeme[] = "This is a test";
int main (void)
{
pid_t pid = fork();
int ret;
int i;
union {
char cdata[8];
int64_t data;
} u = { "Hijacked" };
switch (pid) {
case 0: /* child */
sleep(1);
printf("Message: %s\n", changeme);
exit(0);
case -1:
perror("fork");
exit(1);
break;
default: /* parent */
SHOW(ptrace(PTRACE_ATTACH, pid, 0, 0));
SHOW(ptrace(PTRACE_POKEDATA, pid, changeme, u.data));
SHOW(ptrace(PTRACE_CONT, pid, 0, 0));
wait(NULL);
break;
}
return 0;
}
答案 1 :(得分:1)
ptrace(2)是一个非常神秘的系统调用,仅供调试器等使用。
当然,记录的PTRACE_POKEDATA
ptrace
请求应该有效(当被跟踪的进程停止时)并且使您能够写入被跟踪进程的内存。我不知道写{(mmap
- ing)到/proc/$pid/mem
是否有效。
在linux write /proc /mem
上搜索显示this,这表明/proc/$pid/mem
被设计为只读,但可能在最近的内核中可写。但是来自内核源代码树的最新Documentation/filesystems/proc.txt并没有多说。
我会对/proc/$pid/mem
的写作持谨慎态度;如果它有效(并且它可能没有),它可能是特定于内核版本的。
也许mmap
- /proc/$pid/mem
文件的某些段确实有效(但我不知道)。你试过吗?
相比之下,PTRACE_POKEDATA
应该有效(在Linux存在之前,它已存在于SunOS和许多其他Unix中)。当然,这很慢。