int restore(pink_easy_process_t *current) { pid_t pid = pink_easy_process_get_pid(current); pink_bitness_t bit = pink_easy_process_get_bitness(current); proc_data_t *data = pink_easy_process_get_userdata(current); /* Restore system call number */ if (!pink_util_set_syscall(pid, bit, data->sno)) { if (errno == ESRCH) return PINK_EASY_CFLAG_DROP; warning("pink_util_set_syscall(%lu, %s, %s): errno:%d (%s)", (unsigned long)pid, pink_bitness_name(bit), pink_name_syscall(data->sno, bit), errno, strerror(errno)); } /* Return the saved return value */ if (!pink_util_set_return(pid, data->ret)) { if (errno == ESRCH) return PINK_EASY_CFLAG_DROP; warning("pink_util_set_return(%lu, %s, %s): errno:%d (%s)", (unsigned long)pid, pink_bitness_name(bit), pink_name_syscall(data->sno, bit), errno, strerror(errno)); } return 0; }
static void handle_sigtrap(struct child *son) { long scno, ret; const char *scname; /* We get this event twice, one at entering a * system call and one at exiting a system * call. */ if (son->insyscall) { if (!pink_util_get_return(son->pid, &ret)) err(1, "pink_util_get_return"); if (son->inexecve) { son->inexecve = false; if (ret == 0) { /* execve was successful */ /* Update bitness */ son->bitness = pink_bitness_get(son->pid); if (son->bitness == PINK_BITNESS_UNKNOWN) err(1, "pink_bitness_get"); printf(" = 0 (Updating the bitness of child %i to %s mode)\n", son->pid, pink_bitness_name(son->bitness)); son->printret = false; return; } } son->insyscall = false; if (!son->printret) { son->printret = true; return; } /* Exiting the system call, print the * return value. */ putchar(' '); print_ret(ret); putchar('\n'); } else { son->insyscall = true; /* Get the system call number and call * the appropriate decoder. */ if (!pink_util_get_syscall(son->pid, son->bitness, &scno)) err(1, "pink_util_get_syscall"); scname = pink_name_syscall(scno, son->bitness); assert(scname != NULL); if (!strcmp(scname, "execve")) son->inexecve = true; if (!strcmp(scname, "open")) decode_open(son->pid, son->bitness); else if (!strcmp(scname, "execve")) decode_execve(son->pid, son->bitness); else if (!strcmp(scname, "bind") || !strcmp(scname, "connect")) decode_socketcall(son->pid, son->bitness, scname); else printf("%s()", scname); } }
static void handle_syscall(struct child *son) { long scno; const char *scname; /* We get this event twice, one at entering a * system call and one at exiting a system * call. */ if (son->insyscall) { /* Exiting the system call, print the * return value. */ son->insyscall = false; putchar(' '); print_ret(son->pid); putchar('\n'); } else { /* Get the system call number and call * the appropriate decoder. */ son->insyscall = true; if (!pink_util_get_syscall(son->pid, son->bitness, &scno)) { perror("pink_util_get_syscall"); return; } scname = pink_name_syscall(scno, son->bitness); if (!scname) printf("%ld()", scno); else if (!strcmp(scname, "open")) decode_open(son->pid, son->bitness); else if (!strcmp(scname, "execve")) decode_execve(son->pid, son->bitness); else if (!strcmp(scname, "socketcall") || !strcmp(scname, "bind") || !strcmp(scname, "connect")) decode_socketcall(son->pid, son->bitness, scname); else printf("%s()", scname); } }