diff options
Diffstat (limited to 'toolkit/crashreporter/google-breakpad/src/processor/exploitability_win.cc')
-rw-r--r-- | toolkit/crashreporter/google-breakpad/src/processor/exploitability_win.cc | 283 |
1 files changed, 0 insertions, 283 deletions
diff --git a/toolkit/crashreporter/google-breakpad/src/processor/exploitability_win.cc b/toolkit/crashreporter/google-breakpad/src/processor/exploitability_win.cc deleted file mode 100644 index a1f8703a6..000000000 --- a/toolkit/crashreporter/google-breakpad/src/processor/exploitability_win.cc +++ /dev/null @@ -1,283 +0,0 @@ -// Copyright (c) 2010 Google Inc. -// All rights reserved. -// -// 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 Inc. 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 - -#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; - break; - } - 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 |