Ptrace GETREGS返回NULL寄存器

时间:2013-05-18 10:20:41

标签: c assembly ptrace

我尝试了这段代码(来自http://www.linuxjournal.com/article/6100?page=0,1):

#include <sys/ptrace.h>
#include <sys/reg.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <sys/user.h>
#include <sys/syscall.h>

int main()
{   pid_t child;
  long orig_eax, rax;
  long params[3];
  int status;
  int insyscall = 0;
  struct user_regs_struct regs;

  child = fork();
  if(child == 0) {
    ptrace(PTRACE_TRACEME, 0, NULL, NULL);
    execl("/bin/ls", "ls", NULL);
  }
  else {
    while(1) {
      wait(&status);
      if(WIFEXITED(status))
        break;
      orig_eax = ptrace(PTRACE_PEEKUSER,
                        child, 8 * ORIG_RAX,
                        NULL);
      if(orig_eax == SYS_write) {
        if(insyscall == 0) {
          /* Syscall entry */
          insyscall = 1;
          ptrace(PTRACE_GETREGS, child,
                 NULL, &regs);
          printf("Write called with "
                 "%ld, %ld, %ld\n",
                 regs.rdi, regs.rsi,
                 regs.rdx);
        }
        else { /* Syscall exit */
          rax = ptrace(PTRACE_PEEKUSER,
                       child, 8 * RAX,
                       NULL);
          printf("Write returned "
                 "with %ld\n", rax);
          insyscall = 0;
        }
      }
      ptrace(PTRACE_SYSCALL, child,
             NULL, NULL);
    }
  }
  return 0;
}

这很有效。寄存器rdi获得似乎正确的值。关键是我有一个其他代码返回我的空寄存器,我找不到原因。这是:

void            father_part(pid_t pid)
{
  int           status;
  int           rax;

  wait4(pid, &status, 0, 0);
  while (!WIFEXITED(status))
    {
      rax = ptrace(PTRACE_PEEKUSER, pid, ORIG_RAX * 8, NULL);
      if (rax > 0)
        {
          struct user_regs_struct       regs;
          ptrace(PTRACE_GETREGS, pid, 0, &regs);
          printf("%x\n", regs.rdi); // Here rdi is always NULL
        }
      ptrace(PTRACE_SINGLESTEP, pid, 0, 0);
      wait4(pid, &status, 0, 0);
    }
}

void    child_part(char **av)
{
  ptrace(PTRACE_TRACEME, 0, 0, 0);
  if (execvp(av[1], &av[1]) == -1)
    perror(av[1]);
  exit(0);
}

void    trace_proc(char **av)
{
  pid_t pid;

  pid = fork();
  if (pid == 0)
    child_part(av);
  else
    father_part(pid);
}

int             main(int ac, char **av)
{
  if (ac == 2)
    trace_proc(av);
  return (0);
}

有人能找到第二个代码的错误吗?

0 个答案:

没有答案