1

I am trying to recode a little ftrace which displays syscalls and relative call.

I can catch syscall but I am unable to catch relative call (I read about the PTRACE_PEEKTEXT return value, it works really well with sycall but not with relative call).

Here is my loop:

while (1)                                                            
  {                                                                  
    ptrace(PTRACE_SINGLESTEP, pid, NULL, NULL);                      
    wait4(pid, &status, 0, NULL);                                    
    if (WIFEXITED(status))                                           
      break ;                                                        
    ptrace(PTRACE_GETREGS, pid, NULL, &regs);                        
    if (is_a_syscall(regs, pid))                                     
      printf("Syscall detected\n");                                
    else if (is_a_relative_call(regs, pid) != -1)              
      printf("Relative call detected\n");                                       
  }

And here are the is_a_syscall and is_a_relative_call functions:

int                     is_a_syscall(struct user_regs_struct regs, pid_t pid)                                                            
{                                                                                                                                        
  long          ret;                                                                                                                     
  unsigned char primary;                                                                                                                 
  unsigned char secondary;                                                                                                               

  ret = ptrace(PTRACE_PEEKTEXT, pid, regs.rip, 0);                                                                                       
  primary = (unsigned)0xFF & ret;                                                                                                        
  secondary = ((unsigned)0xFF00 & ret) >> 8;                                                                                             
  if ((primary == 0xCD && secondary == 0x80) || (primary == 0x0F && secondary == 0x05))                                                  
    return (1);                                                                                                                          
  return (0);                                                                                                                            
}                                                                                                                                        

long            is_a_relative_call(struct user_regs_struct regs, pid_t pid)                                                
{                                                                                                                                        
  long          ret;                                                                                                                     
  unsigned char flag;                                                                                                                    

  ret = ptrace(PTRACE_PEEKTEXT, pid, regs.rip + 1, 0);                                                                                   
  flag = ret & 0xff;                                                                                                                     
  if (flag == 0xe8)                                                                                                                      
    return (ret);                                                                                                                        
  else                                                                                                                                   
    return (-1);                  
}

The check of relative call is wrong (with some programs compiled with gcc it displays more than I want and with some programs written in asm I have 0 relative calls detected) but I am unable to find the good way to do that ?

Thank you

melpomene
  • 84,125
  • 8
  • 85
  • 148
void
  • 407
  • 6
  • 18

0 Answers0