int main() { try { test_main(); } catch(exceptions_t e) { std:: cout << "exception caught: " << exception_to_string(e) << std:: endl; } catch( ...) { std::cout << "exception caught" << std::endl; } return 0; }
/* * Returns true if a process exited (so, presumably, we can delete an input * file) */ static bool arch_analyzeSignal(honggfuzz_t * hfuzz, int status, fuzzer_t * fuzzer) { /* * Resumed by delivery of SIGCONT */ if (WIFCONTINUED(status)) { return false; } if (WIFEXITED(status) || WIFSIGNALED(status)) { sancov_Analyze(hfuzz, fuzzer); } /* * Boring, the process just exited */ if (WIFEXITED(status)) { LOG_D("Process (pid %d) exited normally with status %d", fuzzer->pid, WEXITSTATUS(status)); return true; } /* * Shouldn't really happen, but, well.. */ if (!WIFSIGNALED(status)) { LOG_E("Process (pid %d) exited with the following status %d, please report that as a bug", fuzzer->pid, status); return true; } int termsig = WTERMSIG(status); LOG_D("Process (pid %d) killed by signal %d '%s'", fuzzer->pid, termsig, strsignal(termsig)); if (!arch_sigs[termsig].important) { LOG_D("It's not that important signal, skipping"); return true; } /* * Signal is interesting */ /* * Increase crashes counter presented by ASCII display */ ATOMIC_POST_INC(hfuzz->crashesCnt); /* * Get data from exception handler */ fuzzer->pc = g_fuzzer_crash_information[fuzzer->pid].pc; fuzzer->exception = g_fuzzer_crash_information[fuzzer->pid].exception; fuzzer->access = g_fuzzer_crash_information[fuzzer->pid].access; fuzzer->backtrace = g_fuzzer_crash_information[fuzzer->pid].backtrace; defer { if (g_fuzzer_crash_callstack[fuzzer->pid]) { free(g_fuzzer_crash_callstack[fuzzer->pid]); g_fuzzer_crash_callstack[fuzzer->pid] = NULL; } }; /* * Check if stackhash is blacklisted */ if (hfuzz->blacklist && (fastArray64Search(hfuzz->blacklist, hfuzz->blacklistCnt, fuzzer->backtrace) != -1)) { LOG_I("Blacklisted stack hash '%" PRIx64 "', skipping", fuzzer->backtrace); ATOMIC_POST_INC(hfuzz->blCrashesCnt); return true; } /* If dry run mode, copy file with same name into workspace */ if (hfuzz->origFlipRate == 0.0L && hfuzz->useVerifier) { snprintf(fuzzer->crashFileName, sizeof(fuzzer->crashFileName), "%s/%s", hfuzz->workDir, fuzzer->origFileName); } else if (hfuzz->saveUnique) { snprintf(fuzzer->crashFileName, sizeof(fuzzer->crashFileName), "%s/%s.%s.PC.%.16llx.STACK.%.16llx.ADDR.%.16llx.%s", hfuzz->workDir, arch_sigs[termsig].descr, exception_to_string(fuzzer->exception), fuzzer->pc, fuzzer->backtrace, fuzzer->access, hfuzz->fileExtn); } else { char localtmstr[PATH_MAX]; util_getLocalTime("%F.%H.%M.%S", localtmstr, sizeof(localtmstr), time(NULL)); snprintf(fuzzer->crashFileName, sizeof(fuzzer->crashFileName), "%s/%s.%s.PC.%.16llx.STACK.%.16llx.ADDR.%.16llx.TIME.%s.PID.%.5d.%s", hfuzz->workDir, arch_sigs[termsig].descr, exception_to_string(fuzzer->exception), fuzzer->pc, fuzzer->backtrace, fuzzer->access, localtmstr, fuzzer->pid, hfuzz->fileExtn); } if (files_exists(fuzzer->crashFileName)) { LOG_I("It seems that '%s' already exists, skipping", fuzzer->crashFileName); // Clear filename so that verifier can understand we hit a duplicate memset(fuzzer->crashFileName, 0, sizeof(fuzzer->crashFileName)); return true; } if (files_writeBufToFile (fuzzer->crashFileName, fuzzer->dynamicFile, fuzzer->dynamicFileSz, O_CREAT | O_EXCL | O_WRONLY) == false) { LOG_E("Couldn't copy '%s' to '%s'", fuzzer->fileName, fuzzer->crashFileName); return true; } LOG_I("Ok, that's interesting, saved '%s' as '%s'", fuzzer->fileName, fuzzer->crashFileName); ATOMIC_POST_INC(hfuzz->uniqueCrashesCnt); /* If unique crash found, reset dynFile counter */ ATOMIC_CLEAR(hfuzz->dynFileIterExpire); arch_generateReport(fuzzer, termsig); return true; }
// Handle EXCEPTION_DEFAULT behavior kern_return_t catch_mach_exception_raise(mach_port_t exception_port, mach_port_t thread, mach_port_t task, exception_type_t exception, mach_exception_data_t code, mach_msg_type_number_t codeCnt) { int ret, list; char *except; exc_msg_t *exc; interface *face; task_suspend(thread); // Populate structure to give to callback exc = safe_malloc(sizeof(exc_msg_t)); exc->exception_port = exception_port; exc->thread = thread; exc->task = task; exc->exception = exception; exc->code = code; exc->codeCnt = codeCnt; // -1 == failure to handle pass fail to kernel // 0 == continue on // 1 == all done ret = -1; face = find_interface(task); //REGISTER EXCEPTION HANDLER LOOP THROUGH EXCEPTION LIST CALLING EXCEPTION HANDLED FUNCITONS FIRST for(list = 0; list < face->current_exception; list++) { if(face->except_list[list]->exception == exception) { ret = face->except_list[list]->handler(exc); if(ret == -1) { return KERN_FAILURE; } else if(ret == 1){ return KERN_SUCCESS; } } } switch(exception) { case EXC_BREAKPOINT: //DEFAULT BREAKPOINT HANDLE HANDLED AFTER EXCEPTIONS ARE HANDLED if(face->single_step == NULL) { ret = handle_break(exc); if(ret == -1) { DEBUG_PRINT("[-catch_mach_exception_raise] HANDLE BREAK FAILURE %d\n", -1); return KERN_FAILURE; } } else { persistent_break(exc); break; } break; case EXC_SOFTWARE : /* Software generated exception */ //INT3 case EXC_BAD_ACCESS : /* Could not access memory */ case EXC_BAD_INSTRUCTION: /* Instruction failed */ case EXC_ARITHMETIC : /* Arithmetic exception */ case EXC_EMULATION : /* Emulation instruction */ case EXC_SYSCALL : /* System calls. */ case EXC_MACH_SYSCALL : /* Mach system calls. */ case EXC_RPC_ALERT : /* RPC alert */ case EXC_CRASH : /* Abnormal process exit */ case EXC_RESOURCE : /* Hit resource consumption limit */ case EXC_GUARD : /* Violated guarded resource protections */ default: if (ret == 0){ break; } except = exception_to_string(exception); DEBUG_PRINT("[-catch_exception_raise] UNHANDLED EXCEPTION %s\n", except); thread_terminate(thread); break; } task_resume(thread); free(exc); return KERN_SUCCESS; }