Writing memory of the traced process.

2020-02-26 11:52发布

I am playing around with ptrace in linux. I am trying to write the memory of the traced process using /proc/pid/mem interface.

the function I ma using for accomplish this task is :

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;

}

But I always get the error : Writing: Bad file descriptor.

Is it possible to write the traced process using this method?

2条回答
爱情/是我丢掉的垃圾
2楼-- · 2020-02-26 12:50

You are opening the file in read-only mode (O_RDONLY). I'd suggest trying again with O_RDWR instead:

  mem_fd = open(mem_file_name, O_RDWR);

However, from man proc it's not clear this will work:

   /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).

EDIT:

I was curious too, so I put together this example using just ptrace() directly:

#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;
}
查看更多
你好瞎i
3楼-- · 2020-02-26 12:50

ptrace(2) is a very arcane syscall, only used by debuggers and the like.

For sure, the documented PTRACE_POKEDATA request to ptrace should work (when the traced process is stopped) and gives you the ability to write into the memory of the traced process. I don't know if writing (or mmap-ing) to /proc/$pid/mem should work or not.

Googling on linux write /proc /mem give me notably this which suggests that /proc/$pid/mem was designed to be read-only, but might have been made writable in recent kernels. But recent Documentation/filesystems/proc.txt from kernel source tree don't say much.

I would be cautious about writing on /proc/$pid/mem; if it works (and it might not) it probably is very kernel version specific.

Perhaps mmap-ing some segments of that /proc/$pid/mem file does work (but I don't know). Have you tried that?

In contrast, PTRACE_POKEDATA should work (it has existed in SunOS and many other Unixes before Linux existed). Of course, it is fairly slow.

查看更多
登录 后发表回答