bool arch_ptraceAttach(pid_t pid) { #define MAX_THREAD_IN_TASK 4096 int tasks[MAX_THREAD_IN_TASK + 1]; tasks[MAX_THREAD_IN_TASK] = 0; if (!arch_listThreads(tasks, MAX_THREAD_IN_TASK, pid)) { LOGMSG(l_ERROR, "Couldn't read thread list for pid '%d'", pid); return false; } for (int i = 0; i < MAX_THREAD_IN_TASK && tasks[i]; i++) { if (ptrace (PTRACE_SEIZE, tasks[i], NULL, PTRACE_O_TRACECLONE | PTRACE_O_TRACEFORK | PTRACE_O_TRACEVFORK | PTRACE_O_TRACEEXIT) == -1) { LOGMSG_P(l_ERROR, "Couldn't ptrace(PTRACE_SEIZE) to pid: %d", tasks[i]); return false; } LOGMSG(l_DEBUG, "Successfully attached to pid/tid: %d", tasks[i]); } for (int i = 0; i < MAX_THREAD_IN_TASK && tasks[i]; i++) { ptrace(PT_CONTINUE, tasks[i], NULL, NULL); } return true; }
bool arch_ptraceAttach(pid_t pid) { static const long seize_options = PTRACE_O_TRACECLONE | PTRACE_O_TRACEFORK | PTRACE_O_TRACEVFORK | PTRACE_O_TRACEEXIT | PTRACE_O_EXITKILL; if (ptrace(PTRACE_SEIZE, pid, NULL, seize_options) == -1) { PLOG_W("Couldn't ptrace(PTRACE_SEIZE) to pid: %d", pid); return false; } LOG_D("Attached to PID: %d", pid); int tasks[MAX_THREAD_IN_TASK + 1] = { 0 }; if (!arch_listThreads(tasks, MAX_THREAD_IN_TASK, pid)) { LOG_E("Couldn't read thread list for pid '%d'", pid); return false; } for (int i = 0; i < MAX_THREAD_IN_TASK && tasks[i]; i++) { if (tasks[i] == pid) { continue; } if (ptrace(PTRACE_SEIZE, tasks[i], NULL, seize_options) == -1) { PLOG_W("Couldn't ptrace(PTRACE_SEIZE) to pid: %d", tasks[i]); continue; } LOG_D("Attached to PID: %d (thread_group:%d)", tasks[i], pid); } return true; }
bool arch_prepareParent(honggfuzz_t * hfuzz) { if (!hfuzz->pid) { return true; } #define MAX_THREAD_IN_TASK 4096 int tasks[MAX_THREAD_IN_TASK + 1]; tasks[MAX_THREAD_IN_TASK] = 0; if (!arch_listThreads(tasks, MAX_THREAD_IN_TASK, hfuzz->pid)) { LOGMSG(l_ERROR, "Couldn't read thread list for pid '%d'", hfuzz->pid); return false; } for (int i = 0; i < MAX_THREAD_IN_TASK && tasks[i]; i++) { if (ptrace(PT_ATTACH, tasks[i], NULL, NULL) == -1) { LOGMSG_P(l_ERROR, "Couldn't ptrace() ATTACH to pid: %d", tasks[i]); return false; } int status; while (waitpid(tasks[i], &status, WUNTRACED | __WALL) != tasks[i]) ; if (ptrace(PT_CONTINUE, tasks[i], NULL, NULL) == -1) { LOGMSG_P(l_ERROR, "Couldn't ptrace() CONTINUE pid: %d", tasks[i]); ptrace(PT_DETACH, tasks[i], 0, SIGCONT); return false; } LOGMSG(l_INFO, "Successfully attached to pid/tid: %d", tasks[i]); } return true; }
void arch_ptraceDetach(pid_t pid) { if (syscall(__NR_kill, pid, 0) == -1 && errno == ESRCH) { LOG_D("PID: %d no longer exists", pid); return; } int tasks[MAX_THREAD_IN_TASK + 1] = { 0 }; if (!arch_listThreads(tasks, MAX_THREAD_IN_TASK, pid)) { LOG_E("Couldn't read thread list for pid '%d'", pid); return; } for (int i = 0; i < MAX_THREAD_IN_TASK && tasks[i]; i++) { ptrace(PTRACE_INTERRUPT, tasks[i], NULL, NULL); arch_ptraceWaitForPidStop(tasks[i]); ptrace(PTRACE_DETACH, tasks[i], NULL, NULL); } }