LLVM  4.0.0
FuzzerUtilWindows.cpp
Go to the documentation of this file.
1 //===- FuzzerUtilWindows.cpp - Misc utils for Windows. --------------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 // Misc utils implementation for Windows.
10 //===----------------------------------------------------------------------===//
11 #include "FuzzerDefs.h"
12 #if LIBFUZZER_WINDOWS
13 #include "FuzzerIO.h"
14 #include "FuzzerInternal.h"
15 #include <cassert>
16 #include <chrono>
17 #include <cstring>
18 #include <errno.h>
19 #include <iomanip>
20 #include <signal.h>
21 #include <sstream>
22 #include <stdio.h>
23 #include <sys/types.h>
24 #include <windows.h>
25 #include <Psapi.h>
26 
27 namespace fuzzer {
28 
29 static const FuzzingOptions* HandlerOpt = nullptr;
30 
31 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)
38  break;
39  case EXCEPTION_DATATYPE_MISALIGNMENT:
40  case EXCEPTION_IN_PAGE_ERROR:
41  if (HandlerOpt->HandleBus)
43  break;
44  case EXCEPTION_ILLEGAL_INSTRUCTION:
45  case EXCEPTION_PRIV_INSTRUCTION:
46  if (HandlerOpt->HandleIll)
48  break;
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)
60  break;
61  // TODO: handle (Options.HandleXfsz)
62  }
63  return EXCEPTION_CONTINUE_SEARCH;
64 }
65 
66 BOOL WINAPI CtrlHandler(DWORD dwCtrlType) {
67  switch (dwCtrlType) {
68  case CTRL_C_EVENT:
69  if (HandlerOpt->HandleInt)
71  return TRUE;
72  case CTRL_BREAK_EVENT:
73  if (HandlerOpt->HandleTerm)
75  return TRUE;
76  }
77  return FALSE;
78 }
79 
80 void CALLBACK AlarmHandler(PVOID, BOOLEAN) {
82 }
83 
84 class TimerQ {
85  HANDLE TimerQueue;
86  public:
87  TimerQ() : TimerQueue(NULL) {};
88  ~TimerQ() {
89  if (TimerQueue)
90  DeleteTimerQueueEx(TimerQueue, NULL);
91  };
92  void SetTimer(int Seconds) {
93  if (!TimerQueue) {
94  TimerQueue = CreateTimerQueue();
95  if (!TimerQueue) {
96  Printf("libFuzzer: CreateTimerQueue failed.\n");
97  exit(1);
98  }
99  }
100  HANDLE Timer;
101  if (!CreateTimerQueueTimer(&Timer, TimerQueue, AlarmHandler, NULL,
102  Seconds*1000, Seconds*1000, 0)) {
103  Printf("libFuzzer: CreateTimerQueueTimer failed.\n");
104  exit(1);
105  }
106  };
107 };
108 
109 static TimerQ Timer;
110 
111 static void CrashHandler(int) { Fuzzer::StaticCrashSignalCallback(); }
112 
113 void SetSignalHandler(const FuzzingOptions& Options) {
114  HandlerOpt = &Options;
115 
116  if (Options.UnitTimeoutSec > 0)
117  Timer.SetTimer(Options.UnitTimeoutSec / 2 + 1);
118 
119  if (Options.HandleInt || Options.HandleTerm)
120  if (!SetConsoleCtrlHandler(CtrlHandler, TRUE)) {
121  DWORD LastError = GetLastError();
122  Printf("libFuzzer: SetConsoleCtrlHandler failed (Error code: %lu).\n",
123  LastError);
124  exit(1);
125  }
126 
127  if (Options.HandleSegv || Options.HandleBus || Options.HandleIll ||
128  Options.HandleFpe)
129  if (!AddVectoredExceptionHandler(1, ExceptionHandler)) {
130  Printf("libFuzzer: AddVectoredExceptionHandler failed.\n");
131  exit(1);
132  }
133 
134  if (Options.HandleAbrt)
135  if (SIG_ERR == signal(SIGABRT, CrashHandler)) {
136  Printf("libFuzzer: signal failed with %d\n", errno);
137  exit(1);
138  }
139 }
140 
141 void SleepSeconds(int Seconds) { Sleep(Seconds * 1000); }
142 
143 unsigned long GetPid() { return GetCurrentProcessId(); }
144 
145 size_t GetPeakRSSMb() {
146  PROCESS_MEMORY_COUNTERS info;
147  if (!GetProcessMemoryInfo(GetCurrentProcess(), &info, sizeof(info)))
148  return 0;
149  return info.PeakWorkingSetSize >> 20;
150 }
151 
152 FILE *OpenProcessPipe(const char *Command, const char *Mode) {
153  return _popen(Command, Mode);
154 }
155 
156 int ExecuteCommand(const std::string &Command) {
157  return system(Command.c_str());
158 }
159 
160 const void *SearchMemory(const void *Data, size_t DataLen, const void *Patt,
161  size_t PattLen) {
162  // TODO: make this implementation more efficient.
163  const char *Cdata = (const char *)Data;
164  const char *Cpatt = (const char *)Patt;
165 
166  if (!Data || !Patt || DataLen == 0 || PattLen == 0 || DataLen < PattLen)
167  return NULL;
168 
169  if (PattLen == 1)
170  return memchr(Data, *Cpatt, DataLen);
171 
172  const char *End = Cdata + DataLen - PattLen + 1;
173 
174  for (const char *It = Cdata; It < End; ++It)
175  if (It[0] == Cpatt[0] && memcmp(It, Cpatt, PattLen) == 0)
176  return It;
177 
178  return NULL;
179 }
180 
181 } // namespace fuzzer
182 
183 #endif // LIBFUZZER_WINDOWS
SI Whole Quad Mode
void SleepSeconds(int Seconds)
lazy value info
void Printf(const char *Fmt,...)
Definition: FuzzerIO.cpp:109
FILE * OpenProcessPipe(const char *Command, const char *Mode)
static const unsigned End
void SetSignalHandler(const FuzzingOptions &Options)
const void * SearchMemory(const void *haystack, size_t haystacklen, const void *needle, size_t needlelen)
unsigned long GetPid()
size_t GetPeakRSSMb()
Definition: afl_driver.cpp:113
static void CrashHandler(void *)
CrashHandler - This callback is run if a fatal signal is delivered to the process, it prints the pretty stack trace.
static void StaticAlarmCallback()
Definition: FuzzerLoop.cpp:254
static void StaticInterruptCallback()
Definition: FuzzerLoop.cpp:264
int ExecuteCommand(const std::string &Command)
static void StaticCrashSignalCallback()
Definition: FuzzerLoop.cpp:259