blob: c149699e588e9a518c4f3677002314fbaea1252e [file] [log] [blame]
Zachary Turner6fa57ad2016-12-02 23:02:01 +00001//===- 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
12#include "FuzzerDefs.h"
13#if LIBFUZZER_WINDOWS
14#include "FuzzerIO.h"
15#include "FuzzerInternal.h"
16#include <Psapi.h>
17#include <cassert>
18#include <chrono>
19#include <cstring>
20#include <errno.h>
21#include <iomanip>
22#include <signal.h>
23#include <sstream>
24#include <stdio.h>
25#include <sys/types.h>
26#include <windows.h>
27
28namespace fuzzer {
29
30LONG WINAPI SEGVHandler(PEXCEPTION_POINTERS ExceptionInfo) {
31 switch (ExceptionInfo->ExceptionRecord->ExceptionCode) {
32 case EXCEPTION_ACCESS_VIOLATION:
33 case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
34 case EXCEPTION_STACK_OVERFLOW:
35 Fuzzer::StaticCrashSignalCallback();
36 break;
37 }
38 return EXCEPTION_CONTINUE_SEARCH;
39}
40
41LONG WINAPI BUSHandler(PEXCEPTION_POINTERS ExceptionInfo) {
42 switch (ExceptionInfo->ExceptionRecord->ExceptionCode) {
43 case EXCEPTION_DATATYPE_MISALIGNMENT:
44 case EXCEPTION_IN_PAGE_ERROR:
45 Fuzzer::StaticCrashSignalCallback();
46 break;
47 }
48 return EXCEPTION_CONTINUE_SEARCH;
49}
50
51LONG WINAPI ILLHandler(PEXCEPTION_POINTERS ExceptionInfo) {
52 switch (ExceptionInfo->ExceptionRecord->ExceptionCode) {
53 case EXCEPTION_ILLEGAL_INSTRUCTION:
54 case EXCEPTION_PRIV_INSTRUCTION:
55 Fuzzer::StaticCrashSignalCallback();
56 break;
57 }
58 return EXCEPTION_CONTINUE_SEARCH;
59}
60
61LONG WINAPI FPEHandler(PEXCEPTION_POINTERS ExceptionInfo) {
62 switch (ExceptionInfo->ExceptionRecord->ExceptionCode) {
63 case EXCEPTION_FLT_DENORMAL_OPERAND:
64 case EXCEPTION_FLT_DIVIDE_BY_ZERO:
65 case EXCEPTION_FLT_INEXACT_RESULT:
66 case EXCEPTION_FLT_INVALID_OPERATION:
67 case EXCEPTION_FLT_OVERFLOW:
68 case EXCEPTION_FLT_STACK_CHECK:
69 case EXCEPTION_FLT_UNDERFLOW:
70 case EXCEPTION_INT_DIVIDE_BY_ZERO:
71 case EXCEPTION_INT_OVERFLOW:
72 Fuzzer::StaticCrashSignalCallback();
73 break;
74 }
75 return EXCEPTION_CONTINUE_SEARCH;
76}
77
78BOOL WINAPI INTHandler(DWORD dwCtrlType) {
79 switch (dwCtrlType) {
80 case CTRL_C_EVENT:
81 Fuzzer::StaticInterruptCallback();
82 return TRUE;
83 default:
84 return FALSE;
85 }
86}
87
88BOOL WINAPI TERMHandler(DWORD dwCtrlType) {
89 switch (dwCtrlType) {
90 case CTRL_BREAK_EVENT:
91 Fuzzer::StaticInterruptCallback();
92 return TRUE;
93 default:
94 return FALSE;
95 }
96}
97
Marcos Pividori681e9042016-12-12 23:25:11 +000098void CALLBACK AlarmHandler(PVOID, BOOLEAN) {
99 Fuzzer::StaticAlarmCallback();
100}
101
102class TimerQ {
103 HANDLE TimerQueue;
104 public:
105 TimerQ() : TimerQueue(NULL) {};
106 ~TimerQ() {
107 if (TimerQueue)
108 DeleteTimerQueueEx(TimerQueue, NULL);
109 };
110 void SetTimer(int Seconds) {
111 if (!TimerQueue) {
112 TimerQueue = CreateTimerQueue();
113 if (!TimerQueue) {
114 Printf("libFuzzer: CreateTimerQueue failed.\n");
115 exit(1);
116 }
117 }
118 HANDLE Timer;
119 if (!CreateTimerQueueTimer(&Timer, TimerQueue, AlarmHandler, NULL,
120 Seconds*1000, Seconds*1000, 0)) {
121 Printf("libFuzzer: CreateTimerQueueTimer failed.\n");
122 exit(1);
123 }
124 };
125};
126
127static TimerQ Timer;
128
Zachary Turner6fa57ad2016-12-02 23:02:01 +0000129void SetTimer(int Seconds) {
Marcos Pividori681e9042016-12-12 23:25:11 +0000130 Timer.SetTimer(Seconds);
Zachary Turner6fa57ad2016-12-02 23:02:01 +0000131 return;
132}
133
134void SetSigSegvHandler() {
135 if (!AddVectoredExceptionHandler(1, SEGVHandler)) {
136 Printf("libFuzzer: AddVectoredExceptionHandler failed.\n");
137 exit(1);
138 }
139}
140
141void SetSigBusHandler() {
142 if (!AddVectoredExceptionHandler(1, BUSHandler)) {
143 Printf("libFuzzer: AddVectoredExceptionHandler failed.\n");
144 exit(1);
145 }
146}
147
148static void CrashHandler(int) { Fuzzer::StaticCrashSignalCallback(); }
149
150void SetSigAbrtHandler() { signal(SIGABRT, CrashHandler); }
151
152void SetSigIllHandler() {
153 if (!AddVectoredExceptionHandler(1, ILLHandler)) {
154 Printf("libFuzzer: AddVectoredExceptionHandler failed.\n");
155 exit(1);
156 }
157}
158
159void SetSigFpeHandler() {
160 if (!AddVectoredExceptionHandler(1, FPEHandler)) {
161 Printf("libFuzzer: AddVectoredExceptionHandler failed.\n");
162 exit(1);
163 }
164}
165
166void SetSigIntHandler() {
167 if (!SetConsoleCtrlHandler(INTHandler, TRUE)) {
168 DWORD LastError = GetLastError();
169 Printf("libFuzzer: SetConsoleCtrlHandler failed (Error code: %lu).\n",
170 LastError);
171 exit(1);
172 }
173}
174
175void SetSigTermHandler() {
176 if (!SetConsoleCtrlHandler(TERMHandler, TRUE)) {
177 DWORD LastError = GetLastError();
178 Printf("libFuzzer: SetConsoleCtrlHandler failed (Error code: %lu).\n",
179 LastError);
180 exit(1);
181 }
182}
183
184void SleepSeconds(int Seconds) { Sleep(Seconds * 1000); }
185
186int GetPid() { return GetCurrentProcessId(); }
187
188size_t GetPeakRSSMb() {
189 PROCESS_MEMORY_COUNTERS info;
190 if (!GetProcessMemoryInfo(GetCurrentProcess(), &info, sizeof(info)))
191 return 0;
192 return info.PeakWorkingSetSize >> 20;
193}
194
195FILE *OpenProcessPipe(const char *Command, const char *Mode) {
196 return _popen(Command, Mode);
197}
198
199int ExecuteCommand(const std::string &Command) {
200 return system(Command.c_str());
201}
202
203const void *SearchMemory(const void *Data, size_t DataLen, const void *Patt,
204 size_t PattLen) {
205 // TODO: make this implementation more efficient.
206 const char *Cdata = (const char *)Data;
207 const char *Cpatt = (const char *)Patt;
208
209 if (!Data || !Patt || DataLen == 0 || PattLen == 0 || DataLen < PattLen)
210 return NULL;
211
212 if (PattLen == 1)
213 return memchr(Data, *Cpatt, DataLen);
214
215 const char *End = Cdata + DataLen - PattLen;
216
217 for (const char *It = Cdata; It < End; ++It)
218 if (It[0] == Cpatt[0] && memcmp(It, Cpatt, PattLen) == 0)
219 return It;
220
221 return NULL;
222}
223
224} // namespace fuzzer
225#endif // LIBFUZZER_WINDOWS