【问题标题】:Writing memory of the traced process.写入被跟踪进程的内存。
【发布时间】:2013-03-23 10:51:27
【问题描述】:

我在 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;

}

但我总是收到错误消息:Writing: Bad file descriptor。

是否可以使用这种方法编写被跟踪的进程?

【问题讨论】:

  • 你为什么要问? ptrace 的用例是什么?

标签: linux linux-kernel linux-device-driver


【解决方案1】:

您正在以只读模式 (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;
}

【讨论】:

  • 我不确定它是否应该工作...也许mmap-ing 该文件可能会更好...但是,O_RDWR 需要在open 时间(但可能不起作用对于/proc/*pid/mem ...我不知道...)
  • 你是对的。唯一的问题是我以只读模式打开文件。复制和粘贴是大多数错误的来源……啊哈!谢谢!!但是,PTRACE_POKEDATA 不是一个很好的解决方案,您每次只能写入 4 (x32) 或 8 (x64)。这个问题的最佳解决方案是:man7.org/linux/man-pages/man2/process_vm_readv.2.html
【解决方案2】:

ptrace(2) 是一个非常神秘的系统调用,仅由调试器等使用。

当然,记录在案的PTRACE_POKEDATAptrace 的请求应该可以工作(当跟踪进程停止时),并让您能够写入跟踪进程的内存。我不知道写(或mmap-ing)到/proc/$pid/mem 是否可行。

linux write /proc /mem 上谷歌搜索给我特别是this,这表明/proc/$pid/mem 被设计为只读,但在最近的内核中可能已被设为可写。不过最近来自内核源码树的Documentation/filesystems/proc.txt就不多说了。

/proc/$pid/mem 上写信我会很谨慎;如果它有效(也可能无效),它可能是非常特定于内核版本的。

也许mmap-ing 该/proc/$pid/mem 文件的某些部分确实有效(但我不知道)。你试过吗?

相比之下,PTRACE_POKEDATA 应该可以工作(在 Linux 出现之前,它已经存在于 SunOS 和许多其他 Unix 中)。当然,它相当慢。

【讨论】:

  • Ptrace_POKEDATA 提供低带宽来传输数据。当您说要小心使用此方法时,您是对的...这种方法有些混乱,因为当可以写入跟踪进程的内存时,内核中引入了一个错误。有关更多信息,请查看此链接:lwn.net/Articles/476947
猜你喜欢
  • 2010-10-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-14
  • 1970-01-01
  • 2011-09-09
相关资源
最近更新 更多