void *proc_mmap(struct proc *p, int prot, int flags) { void *addr = NULL; char *code = "\xcd\x80\x00\x00\x00\x00\x00\x00"; proc_save(p); p->regs = p->oregs; p->regs.rax = SYS_mmap; p->regs.rdi = 0; p->regs.rsi = 4; p->regs.rdx = prot; p->regs.r10 = flags; p->regs.r8 = -1; p->regs.r9 = 0; p->regs.rip = EBASE; char savebuf[8] = {0}; int n = proc_read(p, (void*)EBASE, savebuf, 8); if (n != 8) { perror("read"); exit(1); } n = proc_write(p, (void*)EBASE, code, 8); if (n != 8) { perror("write"); exit(1); } proc_regs(p, 1); printf("syscall mmap begin...\n"); ptrace(PTRACE_SYSCALL, p->pid, NULL, NULL); while (1) { proc_wait(p); if (p->stat != SYSCALL_STOP) { goto cont; } proc_regs(p, 0); if (p->regs.orig_rax == SYS_mmap) { if (p->insys == 0) { p->insys = 1; } else if (p->insys == 1) { addr = (void *)p->regs.rax; p->insys = 0; break; } } cont: ptrace(PTRACE_SYSCALL, p->pid, NULL, NULL); } proc_write(p, (void *)EBASE, savebuf, 4); proc_restore(p); return addr; }
int proc_mprotect(struct proc *p, void *addr, int prot) { int ret = 0; unsigned long err = 0; char *code = "\x0f\x05\x00\x00\x00\x00\x00\x00"; proc_save(p); p->regs = p->oregs; p->regs.rax = SYS_mprotect; p->regs.rdi = (unsigned long)addr; p->regs.rsi = 0x1000; p->regs.rdx = prot; p->regs.rip = EBASE; char savebuf[8] = {0}; int n = proc_read(p, (void*)EBASE, savebuf, 8); if (n != 8) { perror("read"); exit(1); } n = proc_write(p, (void*)EBASE, code, 8); if (n != 8) { perror("write"); exit(1); } proc_regs(p, 1); ptrace(PTRACE_SYSCALL, p->pid, NULL, NULL); while (1) { proc_wait(p); if (p->stat != SYSCALL_STOP) { printf("not syscall\n"); goto cont; } proc_regs(p, 0); if (p->regs.orig_rax == SYS_mprotect) { if (p->insys == 0) { p->insys = 1; } else if (p->insys == 1) { err = p->regs.rax; p->insys = 0; break; } } cont: ptrace(PTRACE_SYSCALL, p->pid, NULL, NULL); } proc_write(p, (void *)EBASE, savebuf, 8); proc_restore(p); printf("%d, %s\n", err, strerror(-err)); return ret; }
int proc_unset_breakpoint(proc_obj_t* obj, brkp_t* brkp) { if (proc_write(obj, brkp->addr, sizeof(addr_t), (char*) &brkp->sinc) == -1) return (-1); brkp->set = 0; return (0); }
void parentWork() { int i; for (i = 0; i < ITERS; ++i) { while (g_shared->flag); ++g_shared->count; sprintf(g_shared->buff, "%s: %d", proc_name, g_shared->count); proc_write(g_shared->buff); g_shared->flag = !g_shared->flag; } }
void proc_exit(struct proc *p, int no) { char *code = "\xcd\x80\x00\x00\x00\x00\x00\x00"; proc_save(p); p->regs = p->oregs; p->regs.rax = SYS_exit; p->regs.rdi = no; p->regs.rip = EBASE; char savebuf[8] = {0}; int n = proc_read(p, (void*)EBASE, savebuf, 8); if (n != 8) { perror("read"); exit(1); } proc_write(p, (void*)EBASE, code, 8); proc_regs(p, 1); printf("syscall exit begin...\n"); ptrace(PTRACE_SYSCALL, p->pid, NULL, NULL); while (1) { proc_wait(p); if (p->stat == DEAD) { printf("%p: ", p->status); if (WIFEXITED(p->status)) { printf("exit code %d\n", WEXITSTATUS(p->status)); } else if (WIFSIGNALED(p->status)) { printf("signal %d\n", WTERMSIG(p->status)); } break; } if (p->stat != SYSCALL_STOP) { goto cont; } proc_regs(p, 0); if (p->regs.orig_rax == SYS_exit) { if (p->insys == 0) { p->insys = 1; } else if (p->insys == 1) { p->insys = 0; break; } } cont: ptrace(PTRACE_SYSCALL, p->pid, NULL, NULL); } }
int main(int argc, char *argv[]) { if (argc != 3) { return 1; } int pid = atoi(argv[1]); unsigned long addr = strtol(argv[2], NULL, 16); struct proc *p = attach(pid); printf("attach %d\n", p->pid); proc_mprotect(p, (void *)(addr & -0x1000), PROT_READ); printf("begin...\n"); assert(p->stat<UNTRACED && p->stat>RUNNING); proc_cont(p, 0); while (1) { proc_wait(p); //printf("stat %d\n", p->stat); if (p->stat == SIGNAL_DELIVER_STOP) { if (WSTOPSIG(p->status) == SIGSEGV) { siginfo_t siginfo; ptrace(PTRACE_GETSIGINFO, p->pid, NULL, &siginfo); printf("memory address %p\n", siginfo.si_addr); if (siginfo.si_addr == (void *)addr) { proc_mprotect(p, (void *)(addr & -0x1000), PROT_READ|PROT_WRITE); ptrace(PTRACE_SINGLESTEP, p->pid, NULL, NULL); proc_wait(p); //fprintf(stderr, "%d %x\n", p->stat, p->status); proc_write(p, (void *)addr, (char *)&locked, 4); proc_mprotect(p, (void *)(addr & -0x1000), PROT_READ); } else { if (siginfo.si_addr >= (void *)(addr & ~0xfff) && siginfo.si_addr < (void *)((addr + 0xfff) & ~0xfff)) { proc_mprotect(p, (void *)(addr & -0x1000), PROT_READ|PROT_WRITE); ptrace(PTRACE_SINGLESTEP, p->pid, NULL, NULL); proc_wait(p); proc_mprotect(p, (void *)(addr & -0x1000), PROT_READ); } } } } proc_cont(p, 0); } //proc_exit(p, 42); proc_detach(p); }
void ProcWriteInt(struct proc *p, void *addr, int n) { char buf[8] = {0}; proc_read(p, addr, buf, 8); memmove(buf, &n, 4); proc_write(p, addr, buf, 8); }