1c5f01b2fSopenharmony_ci//===- FuzzerUtilWindows.cpp - Misc utils for Windows. --------------------===// 2c5f01b2fSopenharmony_ci// 3c5f01b2fSopenharmony_ci// The LLVM Compiler Infrastructure 4c5f01b2fSopenharmony_ci// 5c5f01b2fSopenharmony_ci// This file is distributed under the University of Illinois Open Source 6c5f01b2fSopenharmony_ci// License. See LICENSE.TXT for details. 7c5f01b2fSopenharmony_ci// 8c5f01b2fSopenharmony_ci//===----------------------------------------------------------------------===// 9c5f01b2fSopenharmony_ci// Misc utils implementation for Windows. 10c5f01b2fSopenharmony_ci//===----------------------------------------------------------------------===// 11c5f01b2fSopenharmony_ci#include "FuzzerDefs.h" 12c5f01b2fSopenharmony_ci#if LIBFUZZER_WINDOWS 13c5f01b2fSopenharmony_ci#include "FuzzerIO.h" 14c5f01b2fSopenharmony_ci#include "FuzzerInternal.h" 15c5f01b2fSopenharmony_ci#include <cassert> 16c5f01b2fSopenharmony_ci#include <chrono> 17c5f01b2fSopenharmony_ci#include <cstring> 18c5f01b2fSopenharmony_ci#include <errno.h> 19c5f01b2fSopenharmony_ci#include <iomanip> 20c5f01b2fSopenharmony_ci#include <signal.h> 21c5f01b2fSopenharmony_ci#include <sstream> 22c5f01b2fSopenharmony_ci#include <stdio.h> 23c5f01b2fSopenharmony_ci#include <sys/types.h> 24c5f01b2fSopenharmony_ci#include <windows.h> 25c5f01b2fSopenharmony_ci#include <Psapi.h> 26c5f01b2fSopenharmony_ci 27c5f01b2fSopenharmony_cinamespace fuzzer { 28c5f01b2fSopenharmony_ci 29c5f01b2fSopenharmony_cistatic const FuzzingOptions* HandlerOpt = nullptr; 30c5f01b2fSopenharmony_ci 31c5f01b2fSopenharmony_ciLONG CALLBACK ExceptionHandler(PEXCEPTION_POINTERS ExceptionInfo) { 32c5f01b2fSopenharmony_ci switch (ExceptionInfo->ExceptionRecord->ExceptionCode) { 33c5f01b2fSopenharmony_ci case EXCEPTION_ACCESS_VIOLATION: 34c5f01b2fSopenharmony_ci case EXCEPTION_ARRAY_BOUNDS_EXCEEDED: 35c5f01b2fSopenharmony_ci case EXCEPTION_STACK_OVERFLOW: 36c5f01b2fSopenharmony_ci if (HandlerOpt->HandleSegv) 37c5f01b2fSopenharmony_ci Fuzzer::StaticCrashSignalCallback(); 38c5f01b2fSopenharmony_ci break; 39c5f01b2fSopenharmony_ci case EXCEPTION_DATATYPE_MISALIGNMENT: 40c5f01b2fSopenharmony_ci case EXCEPTION_IN_PAGE_ERROR: 41c5f01b2fSopenharmony_ci if (HandlerOpt->HandleBus) 42c5f01b2fSopenharmony_ci Fuzzer::StaticCrashSignalCallback(); 43c5f01b2fSopenharmony_ci break; 44c5f01b2fSopenharmony_ci case EXCEPTION_ILLEGAL_INSTRUCTION: 45c5f01b2fSopenharmony_ci case EXCEPTION_PRIV_INSTRUCTION: 46c5f01b2fSopenharmony_ci if (HandlerOpt->HandleIll) 47c5f01b2fSopenharmony_ci Fuzzer::StaticCrashSignalCallback(); 48c5f01b2fSopenharmony_ci break; 49c5f01b2fSopenharmony_ci case EXCEPTION_FLT_DENORMAL_OPERAND: 50c5f01b2fSopenharmony_ci case EXCEPTION_FLT_DIVIDE_BY_ZERO: 51c5f01b2fSopenharmony_ci case EXCEPTION_FLT_INEXACT_RESULT: 52c5f01b2fSopenharmony_ci case EXCEPTION_FLT_INVALID_OPERATION: 53c5f01b2fSopenharmony_ci case EXCEPTION_FLT_OVERFLOW: 54c5f01b2fSopenharmony_ci case EXCEPTION_FLT_STACK_CHECK: 55c5f01b2fSopenharmony_ci case EXCEPTION_FLT_UNDERFLOW: 56c5f01b2fSopenharmony_ci case EXCEPTION_INT_DIVIDE_BY_ZERO: 57c5f01b2fSopenharmony_ci case EXCEPTION_INT_OVERFLOW: 58c5f01b2fSopenharmony_ci if (HandlerOpt->HandleFpe) 59c5f01b2fSopenharmony_ci Fuzzer::StaticCrashSignalCallback(); 60c5f01b2fSopenharmony_ci break; 61c5f01b2fSopenharmony_ci } 62c5f01b2fSopenharmony_ci return EXCEPTION_CONTINUE_SEARCH; 63c5f01b2fSopenharmony_ci} 64c5f01b2fSopenharmony_ci 65c5f01b2fSopenharmony_ciBOOL WINAPI CtrlHandler(DWORD dwCtrlType) { 66c5f01b2fSopenharmony_ci switch (dwCtrlType) { 67c5f01b2fSopenharmony_ci case CTRL_C_EVENT: 68c5f01b2fSopenharmony_ci if (HandlerOpt->HandleInt) 69c5f01b2fSopenharmony_ci Fuzzer::StaticInterruptCallback(); 70c5f01b2fSopenharmony_ci return TRUE; 71c5f01b2fSopenharmony_ci case CTRL_BREAK_EVENT: 72c5f01b2fSopenharmony_ci if (HandlerOpt->HandleTerm) 73c5f01b2fSopenharmony_ci Fuzzer::StaticInterruptCallback(); 74c5f01b2fSopenharmony_ci return TRUE; 75c5f01b2fSopenharmony_ci } 76c5f01b2fSopenharmony_ci return FALSE; 77c5f01b2fSopenharmony_ci} 78c5f01b2fSopenharmony_ci 79c5f01b2fSopenharmony_civoid CALLBACK AlarmHandler(PVOID, BOOLEAN) { 80c5f01b2fSopenharmony_ci Fuzzer::StaticAlarmCallback(); 81c5f01b2fSopenharmony_ci} 82c5f01b2fSopenharmony_ci 83c5f01b2fSopenharmony_ciclass TimerQ { 84c5f01b2fSopenharmony_ci HANDLE TimerQueue; 85c5f01b2fSopenharmony_ci public: 86c5f01b2fSopenharmony_ci TimerQ() : TimerQueue(NULL) {}; 87c5f01b2fSopenharmony_ci ~TimerQ() { 88c5f01b2fSopenharmony_ci if (TimerQueue) 89c5f01b2fSopenharmony_ci DeleteTimerQueueEx(TimerQueue, NULL); 90c5f01b2fSopenharmony_ci }; 91c5f01b2fSopenharmony_ci void SetTimer(int Seconds) { 92c5f01b2fSopenharmony_ci if (!TimerQueue) { 93c5f01b2fSopenharmony_ci TimerQueue = CreateTimerQueue(); 94c5f01b2fSopenharmony_ci if (!TimerQueue) { 95c5f01b2fSopenharmony_ci Printf("libFuzzer: CreateTimerQueue failed.\n"); 96c5f01b2fSopenharmony_ci exit(1); 97c5f01b2fSopenharmony_ci } 98c5f01b2fSopenharmony_ci } 99c5f01b2fSopenharmony_ci HANDLE Timer; 100c5f01b2fSopenharmony_ci if (!CreateTimerQueueTimer(&Timer, TimerQueue, AlarmHandler, NULL, 101c5f01b2fSopenharmony_ci Seconds*1000, Seconds*1000, 0)) { 102c5f01b2fSopenharmony_ci Printf("libFuzzer: CreateTimerQueueTimer failed.\n"); 103c5f01b2fSopenharmony_ci exit(1); 104c5f01b2fSopenharmony_ci } 105c5f01b2fSopenharmony_ci }; 106c5f01b2fSopenharmony_ci}; 107c5f01b2fSopenharmony_ci 108c5f01b2fSopenharmony_cistatic TimerQ Timer; 109c5f01b2fSopenharmony_ci 110c5f01b2fSopenharmony_cistatic void CrashHandler(int) { Fuzzer::StaticCrashSignalCallback(); } 111c5f01b2fSopenharmony_ci 112c5f01b2fSopenharmony_civoid SetSignalHandler(const FuzzingOptions& Options) { 113c5f01b2fSopenharmony_ci HandlerOpt = &Options; 114c5f01b2fSopenharmony_ci 115c5f01b2fSopenharmony_ci if (Options.UnitTimeoutSec > 0) 116c5f01b2fSopenharmony_ci Timer.SetTimer(Options.UnitTimeoutSec / 2 + 1); 117c5f01b2fSopenharmony_ci 118c5f01b2fSopenharmony_ci if (Options.HandleInt || Options.HandleTerm) 119c5f01b2fSopenharmony_ci if (!SetConsoleCtrlHandler(CtrlHandler, TRUE)) { 120c5f01b2fSopenharmony_ci DWORD LastError = GetLastError(); 121c5f01b2fSopenharmony_ci Printf("libFuzzer: SetConsoleCtrlHandler failed (Error code: %lu).\n", 122c5f01b2fSopenharmony_ci LastError); 123c5f01b2fSopenharmony_ci exit(1); 124c5f01b2fSopenharmony_ci } 125c5f01b2fSopenharmony_ci 126c5f01b2fSopenharmony_ci if (Options.HandleSegv || Options.HandleBus || Options.HandleIll || 127c5f01b2fSopenharmony_ci Options.HandleFpe) 128c5f01b2fSopenharmony_ci if (!AddVectoredExceptionHandler(1, ExceptionHandler)) { 129c5f01b2fSopenharmony_ci Printf("libFuzzer: AddVectoredExceptionHandler failed.\n"); 130c5f01b2fSopenharmony_ci exit(1); 131c5f01b2fSopenharmony_ci } 132c5f01b2fSopenharmony_ci 133c5f01b2fSopenharmony_ci if (Options.HandleAbrt) 134c5f01b2fSopenharmony_ci if (SIG_ERR == signal(SIGABRT, CrashHandler)) { 135c5f01b2fSopenharmony_ci Printf("libFuzzer: signal failed with %d\n", errno); 136c5f01b2fSopenharmony_ci exit(1); 137c5f01b2fSopenharmony_ci } 138c5f01b2fSopenharmony_ci} 139c5f01b2fSopenharmony_ci 140c5f01b2fSopenharmony_civoid SleepSeconds(int Seconds) { Sleep(Seconds * 1000); } 141c5f01b2fSopenharmony_ci 142c5f01b2fSopenharmony_ciunsigned long GetPid() { return GetCurrentProcessId(); } 143c5f01b2fSopenharmony_ci 144c5f01b2fSopenharmony_cisize_t GetPeakRSSMb() { 145c5f01b2fSopenharmony_ci PROCESS_MEMORY_COUNTERS info; 146c5f01b2fSopenharmony_ci if (!GetProcessMemoryInfo(GetCurrentProcess(), &info, sizeof(info))) 147c5f01b2fSopenharmony_ci return 0; 148c5f01b2fSopenharmony_ci return info.PeakWorkingSetSize >> 20; 149c5f01b2fSopenharmony_ci} 150c5f01b2fSopenharmony_ci 151c5f01b2fSopenharmony_ciFILE *OpenProcessPipe(const char *Command, const char *Mode) { 152c5f01b2fSopenharmony_ci return _popen(Command, Mode); 153c5f01b2fSopenharmony_ci} 154c5f01b2fSopenharmony_ci 155c5f01b2fSopenharmony_ciint ExecuteCommand(const std::string &Command) { 156c5f01b2fSopenharmony_ci return system(Command.c_str()); 157c5f01b2fSopenharmony_ci} 158c5f01b2fSopenharmony_ci 159c5f01b2fSopenharmony_ciconst void *SearchMemory(const void *Data, size_t DataLen, const void *Patt, 160c5f01b2fSopenharmony_ci size_t PattLen) { 161c5f01b2fSopenharmony_ci // TODO: make this implementation more efficient. 162c5f01b2fSopenharmony_ci const char *Cdata = (const char *)Data; 163c5f01b2fSopenharmony_ci const char *Cpatt = (const char *)Patt; 164c5f01b2fSopenharmony_ci 165c5f01b2fSopenharmony_ci if (!Data || !Patt || DataLen == 0 || PattLen == 0 || DataLen < PattLen) 166c5f01b2fSopenharmony_ci return NULL; 167c5f01b2fSopenharmony_ci 168c5f01b2fSopenharmony_ci if (PattLen == 1) 169c5f01b2fSopenharmony_ci return memchr(Data, *Cpatt, DataLen); 170c5f01b2fSopenharmony_ci 171c5f01b2fSopenharmony_ci const char *End = Cdata + DataLen - PattLen + 1; 172c5f01b2fSopenharmony_ci 173c5f01b2fSopenharmony_ci for (const char *It = Cdata; It < End; ++It) 174c5f01b2fSopenharmony_ci if (It[0] == Cpatt[0] && memcmp(It, Cpatt, PattLen) == 0) 175c5f01b2fSopenharmony_ci return It; 176c5f01b2fSopenharmony_ci 177c5f01b2fSopenharmony_ci return NULL; 178c5f01b2fSopenharmony_ci} 179c5f01b2fSopenharmony_ci 180c5f01b2fSopenharmony_ci} // namespace fuzzer 181c5f01b2fSopenharmony_ci 182c5f01b2fSopenharmony_ci#endif // LIBFUZZER_WINDOWS 183