Ptrace hello (virtual) world
Jump to navigation
Jump to search
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/types.h>
- include <sys/wait.h>
- include <unistd.h>
- include <stdio.h>
- include <string.h>
- include <sys/user.h>
- include <asm/ptrace-abi.h>
- 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, ®s);
- if 0
printf("SYSCALL %lld, INOUT %d %x\n",regs.orig_rax,insyscall,status);
- endif
- 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); } }
- endif
- 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)); } }
- endif
- if 1
if(regs.orig_rax == __NR_getpid && insyscall == 1) { regs.rax = 42; ptrace(PTRACE_SETREGS, child, NULL, ®s); }
- endif
if (regs.orig_rax != __NR_execve) insyscall = 1 - insyscall; ptrace(PTRACE_SYSCALL, child, NULL, NULL); } } return 0;
}
</sysntaxhighlight>