// Copyright 2010 Google LLC
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google LLC nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

// exploitability_win.cc: Windows specific exploitability engine.
//
// Provides a guess at the exploitability of the crash for the Windows
// platform given a minidump and process_state.
//
// Author: Cris Neckar

#ifdef HAVE_CONFIG_H
#include <config.h>  // Must come first
#endif

#include <vector>

#include "processor/exploitability_win.h"

#include "common/scoped_ptr.h"
#include "google_breakpad/common/minidump_exception_win32.h"
#include "google_breakpad/processor/minidump.h"
#include "processor/disassembler_x86.h"
#include "processor/logging.h"

#include "third_party/libdisasm/libdis.h"

namespace google_breakpad {

// The cutoff that we use to judge if and address is likely an offset
// from various interesting addresses.
static const uint64_t kProbableNullOffset = 4096;
static const uint64_t kProbableStackOffset = 8192;

// The various cutoffs for the different ratings.
static const size_t kHighCutoff        = 100;
static const size_t kMediumCutoff      = 80;
static const size_t kLowCutoff         = 50;
static const size_t kInterestingCutoff = 25;

// Predefined incremental values for conditional weighting.
static const size_t kTinyBump          = 5;
static const size_t kSmallBump         = 20;
static const size_t kMediumBump        = 50;
static const size_t kLargeBump         = 70;
static const size_t kHugeBump          = 90;

// The maximum number of bytes to disassemble past the program counter.
static const size_t kDisassembleBytesBeyondPC = 2048;

ExploitabilityWin::ExploitabilityWin(Minidump* dump,
                                     ProcessState* process_state)
    : Exploitability(dump, process_state) { }

ExploitabilityRating ExploitabilityWin::CheckPlatformExploitability() {
  MinidumpException* exception = dump_->GetException();
  if (!exception) {
    BPLOG(INFO) << "Minidump does not have exception record.";
    return EXPLOITABILITY_ERR_PROCESSING;
  }

  const MDRawExceptionStream* raw_exception = exception->exception();
  if (!raw_exception) {
    BPLOG(INFO) << "Could not obtain raw exception info.";
    return EXPLOITABILITY_ERR_PROCESSING;
  }

  const MinidumpContext* context = exception->GetContext();
  if (!context) {
    BPLOG(INFO) << "Could not obtain exception context.";
    return EXPLOITABILITY_ERR_PROCESSING;
  }

  MinidumpMemoryList* memory_list = dump_->GetMemoryList();
  bool memory_available = true;
  if (!memory_list) {
    BPLOG(INFO) << "Minidump memory segments not available.";
    memory_available = false;
  }
  uint64_t address = process_state_->crash_address();
  uint32_t exception_code = raw_exception->exception_record.exception_code;

  uint32_t exploitability_weight = 0;

  uint64_t stack_ptr = 0;
  uint64_t instruction_ptr = 0;

  // Getting the instruction pointer.
  if (!context->GetInstructionPointer(&instruction_ptr)) {
    return EXPLOITABILITY_ERR_PROCESSING;
  }

  // Getting the stack pointer.
  if (!context->GetStackPointer(&stack_ptr)) {
    return EXPLOITABILITY_ERR_PROCESSING;
  }

  // Check if we are executing on the stack.
  if (instruction_ptr <= (stack_ptr + kProbableStackOffset) &&
      instruction_ptr >= (stack_ptr - kProbableStackOffset))
    exploitability_weight += kHugeBump;

  switch (exception_code) {
    // This is almost certainly recursion.
    case MD_EXCEPTION_CODE_WIN_STACK_OVERFLOW:
      exploitability_weight += kTinyBump;
      break;

    // These exceptions tend to be benign and we can generally ignore them.
    case MD_EXCEPTION_CODE_WIN_INTEGER_DIVIDE_BY_ZERO:
    case MD_EXCEPTION_CODE_WIN_INTEGER_OVERFLOW:
    case MD_EXCEPTION_CODE_WIN_FLOAT_DIVIDE_BY_ZERO:
    case MD_EXCEPTION_CODE_WIN_FLOAT_INEXACT_RESULT:
    case MD_EXCEPTION_CODE_WIN_FLOAT_OVERFLOW:
    case MD_EXCEPTION_CODE_WIN_FLOAT_UNDERFLOW:
    case MD_EXCEPTION_CODE_WIN_IN_PAGE_ERROR:
      exploitability_weight += kTinyBump;
      break;

    // These exceptions will typically mean that we have jumped where we
    // shouldn't.
    case MD_EXCEPTION_CODE_WIN_ILLEGAL_INSTRUCTION:
    case MD_EXCEPTION_CODE_WIN_FLOAT_INVALID_OPERATION:
    case MD_EXCEPTION_CODE_WIN_PRIVILEGED_INSTRUCTION:
      exploitability_weight += kLargeBump;
      break;

    // These represent bugs in exception handlers.
    case MD_EXCEPTION_CODE_WIN_INVALID_DISPOSITION:
    case MD_EXCEPTION_CODE_WIN_NONCONTINUABLE_EXCEPTION:
      exploitability_weight += kSmallBump;
      break;

    case MD_EXCEPTION_CODE_WIN_HEAP_CORRUPTION:
    case MD_EXCEPTION_CODE_WIN_STACK_BUFFER_OVERRUN:
      exploitability_weight += kHugeBump;
      break;

    case MD_EXCEPTION_CODE_WIN_GUARD_PAGE_VIOLATION:
      exploitability_weight += kLargeBump;
      break;

    case MD_EXCEPTION_CODE_WIN_ACCESS_VIOLATION:
      bool near_null = (address <= kProbableNullOffset);
      bool bad_read = false;
      bool bad_write = false;
      if (raw_exception->exception_record.number_parameters >= 1) {
        MDAccessViolationTypeWin av_type =
            static_cast<MDAccessViolationTypeWin>
            (raw_exception->exception_record.exception_information[0]);
        switch (av_type) {
          case MD_ACCESS_VIOLATION_WIN_READ:
            bad_read = true;
            if (near_null)
              exploitability_weight += kSmallBump;
            else
              exploitability_weight += kMediumBump;
            break;
          case MD_ACCESS_VIOLATION_WIN_WRITE:
            bad_write = true;
            if (near_null)
              exploitability_weight += kSmallBump;
            else
              exploitability_weight += kHugeBump;
            break;
          case MD_ACCESS_VIOLATION_WIN_EXEC:
            if (near_null)
              exploitability_weight += kSmallBump;
            else
              exploitability_weight += kHugeBump;
            break;
          default:
            BPLOG(INFO) << "Unrecognized access violation type.";
            return EXPLOITABILITY_ERR_PROCESSING;
        }
        MinidumpMemoryRegion* instruction_region = 0;
        if (memory_available) {
          instruction_region =
              memory_list->GetMemoryRegionForAddress(instruction_ptr);
        }
        if (!near_null && instruction_region &&
            context->GetContextCPU() == MD_CONTEXT_X86 &&
            (bad_read || bad_write)) {
          // Perform checks related to memory around instruction pointer.
          uint32_t memory_offset =
              instruction_ptr - instruction_region->GetBase();
          uint32_t available_memory =
              instruction_region->GetSize() - memory_offset;
          available_memory = available_memory > kDisassembleBytesBeyondPC ?
              kDisassembleBytesBeyondPC : available_memory;
          if (available_memory) {
            const uint8_t* raw_memory =
                instruction_region->GetMemory() + memory_offset;
            DisassemblerX86 disassembler(raw_memory,
                                         available_memory,
                                         instruction_ptr);
            disassembler.NextInstruction();
            if (bad_read)
              disassembler.setBadRead();
            else
              disassembler.setBadWrite();
            if (disassembler.currentInstructionValid()) {
              // Check if the faulting instruction falls into one of
              // several interesting groups.
              switch (disassembler.currentInstructionGroup()) {
                case libdis::insn_controlflow:
                  exploitability_weight += kLargeBump;
                  break;
                case libdis::insn_string:
                  exploitability_weight += kHugeBump;
                  break;
                default:
                  break;
              }
              // Loop the disassembler through the code and check if it
              // IDed any interesting conditions in the near future.
              // Multiple flags may be set so treat each equally.
              while (disassembler.NextInstruction() &&
                     disassembler.currentInstructionValid() &&
                     !disassembler.endOfBlock())
                continue;
              if (disassembler.flags() & DISX86_BAD_BRANCH_TARGET)
                exploitability_weight += kLargeBump;
              if (disassembler.flags() & DISX86_BAD_ARGUMENT_PASSED)
                exploitability_weight += kTinyBump;
              if (disassembler.flags() & DISX86_BAD_WRITE)
                exploitability_weight += kMediumBump;
              if (disassembler.flags() & DISX86_BAD_BLOCK_WRITE)
                exploitability_weight += kMediumBump;
              if (disassembler.flags() & DISX86_BAD_READ)
                exploitability_weight += kTinyBump;
              if (disassembler.flags() & DISX86_BAD_BLOCK_READ)
                exploitability_weight += kTinyBump;
              if (disassembler.flags() & DISX86_BAD_COMPARISON)
                exploitability_weight += kTinyBump;
            }
          }
        }
        if (!near_null && AddressIsAscii(address))
          exploitability_weight += kMediumBump;
      } else {
        BPLOG(INFO) << "Access violation type parameter missing.";
        return EXPLOITABILITY_ERR_PROCESSING;
      }
  }

  // Based on the calculated weight we return a simplified classification.
  BPLOG(INFO) << "Calculated exploitability weight: " << exploitability_weight;
  if (exploitability_weight >= kHighCutoff)
    return EXPLOITABILITY_HIGH;
  if (exploitability_weight >= kMediumCutoff)
    return EXPLOITABLITY_MEDIUM;
  if (exploitability_weight >= kLowCutoff)
    return EXPLOITABILITY_LOW;
  if (exploitability_weight >= kInterestingCutoff)
    return EXPLOITABILITY_INTERESTING;

  return EXPLOITABILITY_NONE;
}

}  // namespace google_breakpad
