Ptrace hello (virtual) world

From vsd
Revision as of 11:18, 14 March 2017 by Renzo (talk | contribs) (Created page with "Different experiments can be enabled/disabled by swapping "#if 0" and "#if 1" lines. <syntaxhighlight lang=c> #define _GNU_SOURCE #include <sys/ptrace.h> #include <sys/type...")
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

Different experiments can be enabled/disabled by swapping "#if 0" and "#if 1" lines.

<syntaxhighlight lang=c>

  1. define _GNU_SOURCE
  2. include <sys/ptrace.h>
  3. include <sys/types.h>
  4. include <sys/wait.h>
  5. include <unistd.h>
  6. include <stdio.h>
  7. include <string.h>
  8. include <sys/user.h>
  9. include <asm/ptrace-abi.h>
  10. include <asm/unistd.h> /* For SYS_write etc */

int main(int argc, char *argv[1]) { pid_t child;

 int status;
 int insyscall = 0;
 child = fork();
 if(child == 0) {
   ptrace(PTRACE_TRACEME, 0, NULL, NULL);
   argv++;
   execvp(argv[0], argv);
 }
 else {
   while(1) {
     wait(&status);
     if(WIFEXITED(status))
       break;
     struct user_regs_struct regs;
     ptrace(PTRACE_GETREGS, child, NULL, &regs);
  1. if 0
     printf("SYSCALL %lld, INOUT %d %x\n",regs.orig_rax,insyscall,status);
  1. endif
  2. if 0
     if(regs.orig_rax == __NR_write) {
       if(insyscall == 0) {
         printf("write("
             "%lld, 0x%llx, %lld) = ",  regs.rdi, regs.rsi, regs.rdx);
       }
       else { /* Syscall exit */
         printf("%lld\n", regs.rax);
       }
     }
  1. endif
  2. if 0
     if(regs.orig_rax == __NR_write) {
       if(insyscall == 0 && regs.rsi != 0) {
         char s[sizeof(long long)+1];
         *((long long *)s) = ptrace(PTRACE_PEEKDATA, child, regs.rsi, 0);
         s[sizeof(long long)] = 0;
         //printf("string - %s\n", s);
         if (strncmp(s,"ciao",4) == 0) {
           s[0]='m';
         }
         ptrace(PTRACE_POKEDATA, child, regs.rsi, *((long long *)s));
       }
     }
  1. endif
  2. if 1
     if(regs.orig_rax == __NR_getpid && insyscall == 1) {
         regs.rax = 42;
         ptrace(PTRACE_SETREGS, child, NULL, &regs);
     }
  1. endif
     if (regs.orig_rax != __NR_execve)
       insyscall = 1 - insyscall;
     ptrace(PTRACE_SYSCALL,
         child, NULL, NULL);
   }
 }
 return 0;

}

</sysntaxhighlight>