2

我尝试了这段代码(来自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);
}

谁能找到第二个代码有什么问题?

4

0 回答 0