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