Трассировка системных вызовов - PullRequest
0 голосов
/ 18 марта 2012

У меня следующий код:

void
attach_to_pid (int pid, char *username, int pts)
{
  int sys_call_nr = 0;
  struct user_regs_struct regs;
  ptrace (PTRACE_ATTACH, pid, 0, 0);
  waitpid (pid, 0, WCONTINUED);
  ptrace (PTRACE_SETOPTIONS, pid, 0,
          PTRACE_O_TRACESYSGOOD | PTRACE_O_TRACEEXIT);
  while (true)
    {
      ptrace (PTRACE_SYSCALL, pid, 0, 0);
      int status;
      waitpid (pid, &status, WCONTINUED);
      if (status == (SIGTRAP | PTRACE_EVENT_EXIT << 8))
        break;
      ptrace (PTRACE_GETREGS, pid, 0, &regs);
#ifdef __i386__
      sys_call_nr = regs.eax;
#elif __x86_64__
      sys_call_nr = regs.rax;
#else
#error "Unsupported architecture."
#endif
      if (sys_call_nr == __NR_write)
        {
          printf ("read!");
        }
      ptrace (PTRACE_SYSCALL, pid, 0, 0);
      waitpid (pid, &status, WCONTINUED);
ptrace(PTRACE_GETREGS,pid,0,&regs);
printf("%d = %d\n",sys_call_nr,regs.eax);
//ptrace(PTRACE_CONT, pid, 0 , 0);
    }
  ptrace (PTRACE_DETACH, pid, 0, 0);
}

Я получаю странные результаты, как показано ниже:

-514 = -38
-514 = -38
1 = -38
0 = -38
...

Обычно при связывании с strace сеансом sshd,Я всегда получаю вызовы для чтения и записи системных вызовов при записи в оболочку.Но с этой функцией я не получаю эти (поддельные, я полагаю) системные вызовы, только (как вы можете видеть): 1, 0 и так далее ...

Кто-нибудь может мне помочь?Благодаря.

Ответы [ 2 ]

1 голос
/ 27 марта 2012

Вот мое решение:

  struct user_regs_struct regs /*_on_entry, regs_on_exit*/ ;
  ptrace (PTRACE_ATTACH, pid, 0, 0);
  waitpid (pid, 0, WCONTINUED);
  while (true)
    {
      ptrace (PTRACE_SYSCALL, pid, 0, 0);
      int status;
      wait (&status);
#ifdef __i386__
      int eax = ptrace (PTRACE_PEEKUSER, pid, ORIG_EAX * 4, 0);
      ptrace (PTRACE_GETREGS, pid, 0, &regs);
      ptrace (PTRACE_SYSCALL, pid, 0, 0);
      waitpid (pid, &status, WCONTINUED);
      if (eax == __NR_read && regs.ebx == 10)
        {
          int *buffer = (int *) malloc (regs.eax + 3);
          int i = 0;
          for (int j = 0; i < regs.eax; i += 4, j++)
            {
              buffer[j] = ptrace (PTRACE_PEEKTEXT, pid, regs.ecx + i, 0);
            }
          if (regs.edx % 4)     // rest of chunk.
            {
              buffer[i] =
                ptrace (PTRACE_PEEKUSER, pid, regs.ecx + 2 * i - regs.eax, 0);
            }
          write (1, buffer, regs.eax);
          free (buffer);
        }
#elif __x86_64__
#else
#error "Unsupported architecture."
#endif
    }

Спасибо за ответы!

1 голос
/ 20 марта 2012

Даже я боролся с той же проблемой.И ваш вопрос является точной копией этого Ответ там более красиво объяснен.Это моя версия:
Ваша программа должна различать вход системного вызова и выход системного вызова.
Сохранить переменную для этого.Проверьте этот код .Здесь переменная in_syscall делает то же самое.
Надеюсь, это вам поможет.
В следующий раз, когда новички проведут фундаментальное исследование (повторный поиск) здесь, перед тем, как отправлять вопрос.ЭКОНОМИТ МНОГО ВАШЕГО ВРЕМЕНИ;) И наше тоже: D

...