1 //===- FuzzerUtilWindows.cpp - Misc utils for Windows. --------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
9 // Misc utils implementation for Windows.
10 //===----------------------------------------------------------------------===//
11 #include "FuzzerDefs.h"
14 #include "FuzzerInternal.h"
23 #include <sys/types.h>
29 static const FuzzingOptions* HandlerOpt = nullptr;
31 static LONG CALLBACK ExceptionHandler(PEXCEPTION_POINTERS ExceptionInfo) {
32 switch (ExceptionInfo->ExceptionRecord->ExceptionCode) {
33 case EXCEPTION_ACCESS_VIOLATION:
34 case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
35 case EXCEPTION_STACK_OVERFLOW:
36 if (HandlerOpt->HandleSegv)
37 Fuzzer::StaticCrashSignalCallback();
39 case EXCEPTION_DATATYPE_MISALIGNMENT:
40 case EXCEPTION_IN_PAGE_ERROR:
41 if (HandlerOpt->HandleBus)
42 Fuzzer::StaticCrashSignalCallback();
44 case EXCEPTION_ILLEGAL_INSTRUCTION:
45 case EXCEPTION_PRIV_INSTRUCTION:
46 if (HandlerOpt->HandleIll)
47 Fuzzer::StaticCrashSignalCallback();
49 case EXCEPTION_FLT_DENORMAL_OPERAND:
50 case EXCEPTION_FLT_DIVIDE_BY_ZERO:
51 case EXCEPTION_FLT_INEXACT_RESULT:
52 case EXCEPTION_FLT_INVALID_OPERATION:
53 case EXCEPTION_FLT_OVERFLOW:
54 case EXCEPTION_FLT_STACK_CHECK:
55 case EXCEPTION_FLT_UNDERFLOW:
56 case EXCEPTION_INT_DIVIDE_BY_ZERO:
57 case EXCEPTION_INT_OVERFLOW:
58 if (HandlerOpt->HandleFpe)
59 Fuzzer::StaticCrashSignalCallback();
61 // TODO: handle (Options.HandleXfsz)
63 return EXCEPTION_CONTINUE_SEARCH;
66 BOOL WINAPI CtrlHandler(DWORD dwCtrlType) {
69 if (HandlerOpt->HandleInt)
70 Fuzzer::StaticInterruptCallback();
72 case CTRL_BREAK_EVENT:
73 if (HandlerOpt->HandleTerm)
74 Fuzzer::StaticInterruptCallback();
80 void CALLBACK AlarmHandler(PVOID, BOOLEAN) {
81 Fuzzer::StaticAlarmCallback();
87 TimerQ() : TimerQueue(NULL) {};
90 DeleteTimerQueueEx(TimerQueue, NULL);
92 void SetTimer(int Seconds) {
94 TimerQueue = CreateTimerQueue();
96 Printf("libFuzzer: CreateTimerQueue failed.\n");
101 if (!CreateTimerQueueTimer(&Timer, TimerQueue, AlarmHandler, NULL,
102 Seconds*1000, Seconds*1000, 0)) {
103 Printf("libFuzzer: CreateTimerQueueTimer failed.\n");
111 static void CrashHandler(int) { Fuzzer::StaticCrashSignalCallback(); }
113 void SetSignalHandler(const FuzzingOptions& Options) {
114 HandlerOpt = &Options;
116 if (Options.UnitTimeoutSec > 0)
117 Timer.SetTimer(Options.UnitTimeoutSec / 2 + 1);
119 if (Options.HandleInt || Options.HandleTerm)
120 if (!SetConsoleCtrlHandler(CtrlHandler, TRUE)) {
121 DWORD LastError = GetLastError();
122 Printf("libFuzzer: SetConsoleCtrlHandler failed (Error code: %lu).\n",
127 if (Options.HandleSegv || Options.HandleBus || Options.HandleIll ||
129 SetUnhandledExceptionFilter(ExceptionHandler);
131 if (Options.HandleAbrt)
132 if (SIG_ERR == signal(SIGABRT, CrashHandler)) {
133 Printf("libFuzzer: signal failed with %d\n", errno);
138 void SleepSeconds(int Seconds) { Sleep(Seconds * 1000); }
140 unsigned long GetPid() { return GetCurrentProcessId(); }
142 size_t GetPeakRSSMb() {
143 PROCESS_MEMORY_COUNTERS info;
144 if (!GetProcessMemoryInfo(GetCurrentProcess(), &info, sizeof(info)))
146 return info.PeakWorkingSetSize >> 20;
149 FILE *OpenProcessPipe(const char *Command, const char *Mode) {
150 return _popen(Command, Mode);
153 int ExecuteCommand(const std::string &Command) {
154 return system(Command.c_str());
157 const void *SearchMemory(const void *Data, size_t DataLen, const void *Patt,
159 // TODO: make this implementation more efficient.
160 const char *Cdata = (const char *)Data;
161 const char *Cpatt = (const char *)Patt;
163 if (!Data || !Patt || DataLen == 0 || PattLen == 0 || DataLen < PattLen)
167 return memchr(Data, *Cpatt, DataLen);
169 const char *End = Cdata + DataLen - PattLen + 1;
171 for (const char *It = Cdata; It < End; ++It)
172 if (It[0] == Cpatt[0] && memcmp(It, Cpatt, PattLen) == 0)
178 std::string DisassembleCmd(const std::string &FileName) {
179 if (ExecuteCommand("dumpbin /summary > nul") == 0)
180 return "dumpbin /disasm " + FileName;
181 Printf("libFuzzer: couldn't find tool to disassemble (dumpbin)\n");
185 std::string SearchRegexCmd(const std::string &Regex) {
186 return "findstr /r \"" + Regex + "\"";
189 } // namespace fuzzer
191 #endif // LIBFUZZER_WINDOWS