LLVM  6.0.0svn
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 
26 // This must be included after windows.h.
27 #include <Psapi.h>
28 
29 namespace fuzzer {
30 
31 static const FuzzingOptions* HandlerOpt = nullptr;
32 
33 static LONG CALLBACK ExceptionHandler(PEXCEPTION_POINTERS ExceptionInfo) {
34  switch (ExceptionInfo->ExceptionRecord->ExceptionCode) {
35  case EXCEPTION_ACCESS_VIOLATION:
36  case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
37  case EXCEPTION_STACK_OVERFLOW:
38  if (HandlerOpt->HandleSegv)
40  break;
41  case EXCEPTION_DATATYPE_MISALIGNMENT:
42  case EXCEPTION_IN_PAGE_ERROR:
43  if (HandlerOpt->HandleBus)
45  break;
46  case EXCEPTION_ILLEGAL_INSTRUCTION:
47  case EXCEPTION_PRIV_INSTRUCTION:
48  if (HandlerOpt->HandleIll)
50  break;
51  case EXCEPTION_FLT_DENORMAL_OPERAND:
52  case EXCEPTION_FLT_DIVIDE_BY_ZERO:
53  case EXCEPTION_FLT_INEXACT_RESULT:
54  case EXCEPTION_FLT_INVALID_OPERATION:
55  case EXCEPTION_FLT_OVERFLOW:
56  case EXCEPTION_FLT_STACK_CHECK:
57  case EXCEPTION_FLT_UNDERFLOW:
58  case EXCEPTION_INT_DIVIDE_BY_ZERO:
59  case EXCEPTION_INT_OVERFLOW:
60  if (HandlerOpt->HandleFpe)
62  break;
63  // TODO: handle (Options.HandleXfsz)
64  }
65  return EXCEPTION_CONTINUE_SEARCH;
66 }
67 
68 BOOL WINAPI CtrlHandler(DWORD dwCtrlType) {
69  switch (dwCtrlType) {
70  case CTRL_C_EVENT:
71  if (HandlerOpt->HandleInt)
73  return TRUE;
74  case CTRL_BREAK_EVENT:
75  if (HandlerOpt->HandleTerm)
77  return TRUE;
78  }
79  return FALSE;
80 }
81 
82 void CALLBACK AlarmHandler(PVOID, BOOLEAN) {
84 }
85 
86 class TimerQ {
87  HANDLE TimerQueue;
88  public:
89  TimerQ() : TimerQueue(NULL) {};
90  ~TimerQ() {
91  if (TimerQueue)
92  DeleteTimerQueueEx(TimerQueue, NULL);
93  };
94  void SetTimer(int Seconds) {
95  if (!TimerQueue) {
96  TimerQueue = CreateTimerQueue();
97  if (!TimerQueue) {
98  Printf("libFuzzer: CreateTimerQueue failed.\n");
99  exit(1);
100  }
101  }
102  HANDLE Timer;
103  if (!CreateTimerQueueTimer(&Timer, TimerQueue, AlarmHandler, NULL,
104  Seconds*1000, Seconds*1000, 0)) {
105  Printf("libFuzzer: CreateTimerQueueTimer failed.\n");
106  exit(1);
107  }
108  };
109 };
110 
111 static TimerQ Timer;
112 
113 static void CrashHandler(int) { Fuzzer::StaticCrashSignalCallback(); }
114 
115 void SetSignalHandler(const FuzzingOptions& Options) {
116  HandlerOpt = &Options;
117 
118  if (Options.UnitTimeoutSec > 0)
119  Timer.SetTimer(Options.UnitTimeoutSec / 2 + 1);
120 
121  if (Options.HandleInt || Options.HandleTerm)
122  if (!SetConsoleCtrlHandler(CtrlHandler, TRUE)) {
123  DWORD LastError = GetLastError();
124  Printf("libFuzzer: SetConsoleCtrlHandler failed (Error code: %lu).\n",
125  LastError);
126  exit(1);
127  }
128 
129  if (Options.HandleSegv || Options.HandleBus || Options.HandleIll ||
130  Options.HandleFpe)
131  SetUnhandledExceptionFilter(ExceptionHandler);
132 
133  if (Options.HandleAbrt)
134  if (SIG_ERR == signal(SIGABRT, CrashHandler)) {
135  Printf("libFuzzer: signal failed with %d\n", errno);
136  exit(1);
137  }
138 }
139 
140 void SleepSeconds(int Seconds) { Sleep(Seconds * 1000); }
141 
142 unsigned long GetPid() { return GetCurrentProcessId(); }
143 
144 size_t GetPeakRSSMb() {
145  PROCESS_MEMORY_COUNTERS info;
146  if (!GetProcessMemoryInfo(GetCurrentProcess(), &info, sizeof(info)))
147  return 0;
148  return info.PeakWorkingSetSize >> 20;
149 }
150 
151 FILE *OpenProcessPipe(const char *Command, const char *Mode) {
152  return _popen(Command, Mode);
153 }
154 
155 int ExecuteCommand(const std::string &Command) {
156  return system(Command.c_str());
157 }
158 
159 const void *SearchMemory(const void *Data, size_t DataLen, const void *Patt,
160  size_t PattLen) {
161  // TODO: make this implementation more efficient.
162  const char *Cdata = (const char *)Data;
163  const char *Cpatt = (const char *)Patt;
164 
165  if (!Data || !Patt || DataLen == 0 || PattLen == 0 || DataLen < PattLen)
166  return NULL;
167 
168  if (PattLen == 1)
169  return memchr(Data, *Cpatt, DataLen);
170 
171  const char *End = Cdata + DataLen - PattLen + 1;
172 
173  for (const char *It = Cdata; It < End; ++It)
174  if (It[0] == Cpatt[0] && memcmp(It, Cpatt, PattLen) == 0)
175  return It;
176 
177  return NULL;
178 }
179 
180 std::string DisassembleCmd(const std::string &FileName) {
181  if (ExecuteCommand("dumpbin /summary > nul") == 0)
182  return "dumpbin /disasm " + FileName;
183  Printf("libFuzzer: couldn't find tool to disassemble (dumpbin)\n");
184  exit(1);
185 }
186 
187 std::string SearchRegexCmd(const std::string &Regex) {
188  return "findstr /r \"" + Regex + "\"";
189 }
190 
191 } // namespace fuzzer
192 
193 #endif // LIBFUZZER_WINDOWS
SI Whole Quad Mode
void SleepSeconds(int Seconds)
std::string SearchRegexCmd(const std::string &Regex)
void Printf(const char *Fmt,...)
Definition: FuzzerIO.cpp:112
FILE * OpenProcessPipe(const char *Command, const char *Mode)
static const unsigned End
lazy value info
void SetSignalHandler(const FuzzingOptions &Options)
std::string DisassembleCmd(const std::string &FileName)
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:118
static void CrashHandler(void *)
CrashHandler - This callback is run if a fatal signal is delivered to the process, it prints the pretty stack trace.
Merge contiguous icmps into a memcmp
Definition: MergeICmps.cpp:650
static void StaticAlarmCallback()
Definition: FuzzerLoop.cpp:168
static void StaticInterruptCallback()
Definition: FuzzerLoop.cpp:183
int ExecuteCommand(const std::string &Command)
static void StaticCrashSignalCallback()
Definition: FuzzerLoop.cpp:173