This blogpost has first been published in my old blog at spin.
This code uses the ptrace debug interface to attach to a process wait for a write syscall and replace the word “windows” with “*******”.
#include <stdio.h> #include <string.h> #include <sys/ptrace.h> #include <asm/ptrace-abi.h> #include <sys/reg.h> #include <sys/user.h> #include <unistd.h> #include <bits/wordsize.h> #include <sys/types.h> #include <sys/wait.h> int main() { pid_t pid; int i; struct user_regs_struct regs; union u { long val; char str[sizeof(long)+1]; } data; union u olddata; union uu { struct { long v1; long v2; } val; char str[(2*sizeof(long))+1]; } ldata; char *winstring; printf("wordsize: %d\n", __WORDSIZE); printf("pid: "); scanf("%d", &pid); printf("connecting to %d\n", pid); ptrace(PTRACE_ATTACH, pid, NULL, NULL); perror("connect"); getchar(); while (regs.orig_rax != 0xe7) { wait(NULL); ptrace(PTRACE_GETREGS, pid, NULL, ®s); switch (regs.orig_rax) { case 0: printf("read-"); break; case 1: printf("write-"); break; case 2: printf("open-"); break; case 3: printf("close-"); break; } if (regs.orig_rax != -1) { printf("syscall: 0x%lx 0x%lx 0x%lx 0x%lx => 0x%lx\n", regs.orig_rax, regs.rbx, regs.rcx, regs.rdx, regs.rax); printf("\t rdi: 0x%lx rsi: 0x%lx\n", regs.rdi, regs.rsi); } if (regs.orig_rax == 1) { //printf("txt: "); data.val = 0; for (i = 0; i < regs.rdx; i+=sizeof(long)) { olddata.val = data.val; data.val = ptrace(PTRACE_PEEKDATA, pid, regs. rsi+i, NULL); if (i == 0) data.str[regs.rdx] = '\0'; else data.str[sizeof(long)] = '\0'; //printf("%s", data.str); if (olddata.val != 0) { ldata.val.v1 = olddata.val; ldata.val.v2 = data.val; printf("ldata.str: %s\n", ldata.str); winstring = strstr(ldata.str, "windows"); if (winstring != NULL) { strncpy(winstring, "*******", 7); printf("new-ldata.str: %s\n", ldata.str); ptrace(PTRACE_POKEDATA, pid, regs.rsi, ldata.val.v1); ptrace(PTRACE_POKEDATA, pid, regs.rsi+sizeof(long), ldata.val.v2); i+=sizeof(long); } } } printf("\n"); } //printf("cont ...\n"); //getchar(); ptrace(PTRACE_SYSCALL, pid, 1, 0); } ptrace(PTRACE_CONT, pid, NULL, NULL); ptrace(PTRACE_DETACH, pid, NULL, NULL); return 0; }
“0xe7” is the syscall for exit; so it quits instructing the process when that process exits.
A simple program for testing purposes:
#include <stdio.h> int main() { while (1) { printf(" windows \n"); sleep(1); } }