I'm trying to use ptrace to change another program variable at run time, in my case a dummy shell.
int main(void)
{
char buf[MAXLINE];
fgets(buf, MAXLINE, stdin);
if (buf[strlen(buf) - 1] == '\n')
buf[strlen(buf) - 1] = 0;
execlp("sh", "sh", "-c", buf, (char *)0);
printf("couldn't execute: %s", buf);
exit(127);
}
In my injector app I use PTRACE_ATTACH and listen for sys_read syscalls; then PTRACE_GETREGS to try to obtain the registers that should contain the address of the "buf" array.
ptrace(PTRACE_SYSCALL, pid, 0, 0);
wait(&status);
ptrace(PTRACE_GETREGS, pid, 0, ®s);
syscall_n = regs.orig_rax;
if (syscall_n == SYS_read){
switch(syscall_status){
case STARTED:
printf("Waiting user input... ");
syscall_status = WAITING;
break;
case WAITING:
printf("\t[ OK ]\n");
syscall_status = RETURNED;
break;
default:
break;
}
}
While I can catch the correct open syscall when fgets is called, I have no idea in which of the registers I should use to obtain the address of the string array. Or if there is a better way to obtain it.
So I can later use PEEKDATA and POKEDATA to inject the modified string.
Btw, I have read the "Playing with ptrace Part I" article, but I don't understand how adapt it to my purpose.