1cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org// Copyright (c) 2010 Google Inc. 2cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org// All rights reserved. 3cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org// 4cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org// Redistribution and use in source and binary forms, with or without 5cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org// modification, are permitted provided that the following conditions are 6cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org// met: 7cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org// 8cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org// * Redistributions of source code must retain the above copyright 9cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org// notice, this list of conditions and the following disclaimer. 10cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org// * Redistributions in binary form must reproduce the above 11cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org// copyright notice, this list of conditions and the following disclaimer 12cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org// in the documentation and/or other materials provided with the 13cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org// distribution. 14cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org// * Neither the name of Google Inc. nor the names of its 15cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org// contributors may be used to endorse or promote products derived from 16cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org// this software without specific prior written permission. 17cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org// 18cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org 30cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org// exploitability_win.cc: Windows specific exploitability engine. 31cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org// 32cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org// Provides a guess at the exploitability of the crash for the Windows 33cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org// platform given a minidump and process_state. 34cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org// 35cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org// Author: Cris Neckar 36cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org 372b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org#include <vector> 382b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org 39cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org#include "processor/exploitability_win.h" 40cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org 412cc15ba4327831f917ff55b87e6d5fc3c7750085ted.mielczarek@gmail.com#include "common/scoped_ptr.h" 42cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org#include "google_breakpad/common/minidump_exception_win32.h" 432b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org#include "google_breakpad/processor/minidump.h" 442b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org#include "processor/disassembler_x86.h" 45cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org#include "processor/logging.h" 46cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org 472b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org#include "third_party/libdisasm/libdis.h" 482b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org 49cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.orgnamespace google_breakpad { 50cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org 51cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org// The cutoff that we use to judge if and address is likely an offset 522b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org// from various interesting addresses. 536162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.comstatic const uint64_t kProbableNullOffset = 4096; 546162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.comstatic const uint64_t kProbableStackOffset = 8192; 55cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org 56cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org// The various cutoffs for the different ratings. 572b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.orgstatic const size_t kHighCutoff = 100; 582b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.orgstatic const size_t kMediumCutoff = 80; 592b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.orgstatic const size_t kLowCutoff = 50; 60cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.orgstatic const size_t kInterestingCutoff = 25; 61cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org 62cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org// Predefined incremental values for conditional weighting. 63cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.orgstatic const size_t kTinyBump = 5; 64cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.orgstatic const size_t kSmallBump = 20; 65cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.orgstatic const size_t kMediumBump = 50; 66cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.orgstatic const size_t kLargeBump = 70; 67cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.orgstatic const size_t kHugeBump = 90; 68cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org 692b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org// The maximum number of bytes to disassemble past the program counter. 702b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.orgstatic const size_t kDisassembleBytesBeyondPC = 2048; 712b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org 72cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.orgExploitabilityWin::ExploitabilityWin(Minidump *dump, 73cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org ProcessState *process_state) 74cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org : Exploitability(dump, process_state) { } 75cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org 76cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.orgExploitabilityRating ExploitabilityWin::CheckPlatformExploitability() { 77cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org MinidumpException *exception = dump_->GetException(); 782b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org if (!exception) { 792b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org BPLOG(INFO) << "Minidump does not have exception record."; 80cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org return EXPLOITABILITY_ERR_PROCESSING; 812b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org } 82cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org 83cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org const MDRawExceptionStream *raw_exception = exception->exception(); 842b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org if (!raw_exception) { 852b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org BPLOG(INFO) << "Could not obtain raw exception info."; 86cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org return EXPLOITABILITY_ERR_PROCESSING; 872b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org } 88cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org 892b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org const MinidumpContext *context = exception->GetContext(); 902b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org if (!context) { 912b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org BPLOG(INFO) << "Could not obtain exception context."; 922b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org return EXPLOITABILITY_ERR_PROCESSING; 932b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org } 942b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org 952b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org MinidumpMemoryList *memory_list = dump_->GetMemoryList(); 962b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org bool memory_available = true; 972b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org if (!memory_list) { 982b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org BPLOG(INFO) << "Minidump memory segments not available."; 992b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org memory_available = false; 1002b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org } 1016162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint64_t address = process_state_->crash_address(); 1026162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint32_t exception_code = raw_exception->exception_record.exception_code; 103cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org 1046162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint32_t exploitability_weight = 0; 105cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org 1066162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint64_t stack_ptr = 0; 1076162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint64_t instruction_ptr = 0; 1082b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org 1092b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org switch (context->GetContextCPU()) { 1102b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org case MD_CONTEXT_X86: 1112b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org stack_ptr = context->GetContextX86()->esp; 1122b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org instruction_ptr = context->GetContextX86()->eip; 1132b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org break; 1142b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org case MD_CONTEXT_AMD64: 1152b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org stack_ptr = context->GetContextAMD64()->rsp; 1162b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org instruction_ptr = context->GetContextAMD64()->rip; 1172b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org break; 1182b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org default: 1192b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org BPLOG(INFO) << "Unsupported architecture."; 1202b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org return EXPLOITABILITY_ERR_PROCESSING; 1212b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org } 1222b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org 1232b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org // Check if we are executing on the stack. 1242b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org if (instruction_ptr <= (stack_ptr + kProbableStackOffset) && 1252b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org instruction_ptr >= (stack_ptr - kProbableStackOffset)) 1262b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org exploitability_weight += kHugeBump; 1272b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org 128cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org switch (exception_code) { 129cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org // This is almost certainly recursion. 130cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org case MD_EXCEPTION_CODE_WIN_STACK_OVERFLOW: 131cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org exploitability_weight += kTinyBump; 132cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org break; 133cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org 134cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org // These exceptions tend to be benign and we can generally ignore them. 135cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org case MD_EXCEPTION_CODE_WIN_INTEGER_DIVIDE_BY_ZERO: 136cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org case MD_EXCEPTION_CODE_WIN_INTEGER_OVERFLOW: 137cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org case MD_EXCEPTION_CODE_WIN_FLOAT_DIVIDE_BY_ZERO: 138cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org case MD_EXCEPTION_CODE_WIN_FLOAT_INEXACT_RESULT: 139cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org case MD_EXCEPTION_CODE_WIN_FLOAT_OVERFLOW: 140cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org case MD_EXCEPTION_CODE_WIN_FLOAT_UNDERFLOW: 141cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org case MD_EXCEPTION_CODE_WIN_IN_PAGE_ERROR: 142cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org exploitability_weight += kTinyBump; 143cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org break; 144cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org 145cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org // These exceptions will typically mean that we have jumped where we 146cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org // shouldn't. 147cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org case MD_EXCEPTION_CODE_WIN_ILLEGAL_INSTRUCTION: 148cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org case MD_EXCEPTION_CODE_WIN_FLOAT_INVALID_OPERATION: 149cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org case MD_EXCEPTION_CODE_WIN_PRIVILEGED_INSTRUCTION: 150cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org exploitability_weight += kLargeBump; 151cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org break; 152cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org 153cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org // These represent bugs in exception handlers. 154cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org case MD_EXCEPTION_CODE_WIN_INVALID_DISPOSITION: 155cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org case MD_EXCEPTION_CODE_WIN_NONCONTINUABLE_EXCEPTION: 156cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org exploitability_weight += kSmallBump; 157cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org break; 158cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org 159cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org case MD_EXCEPTION_CODE_WIN_HEAP_CORRUPTION: 160cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org case MD_EXCEPTION_CODE_WIN_STACK_BUFFER_OVERRUN: 161cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org exploitability_weight += kHugeBump; 162cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org break; 163cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org 164cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org case MD_EXCEPTION_CODE_WIN_GUARD_PAGE_VIOLATION: 165cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org exploitability_weight += kLargeBump; 166cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org break; 167cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org 168cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org case MD_EXCEPTION_CODE_WIN_ACCESS_VIOLATION: 169cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org bool near_null = (address <= kProbableNullOffset); 1702b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org bool bad_read = false; 1712b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org bool bad_write = false; 172cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org if (raw_exception->exception_record.number_parameters >= 1) { 173cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org MDAccessViolationTypeWin av_type = 174cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org static_cast<MDAccessViolationTypeWin> 175cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org (raw_exception->exception_record.exception_information[0]); 176cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org switch (av_type) { 177cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org case MD_ACCESS_VIOLATION_WIN_READ: 1782b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org bad_read = true; 179cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org if (near_null) 180cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org exploitability_weight += kSmallBump; 181cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org else 182cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org exploitability_weight += kMediumBump; 183cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org break; 184cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org case MD_ACCESS_VIOLATION_WIN_WRITE: 1852b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org bad_write = true; 186cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org if (near_null) 187cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org exploitability_weight += kSmallBump; 188cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org else 189cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org exploitability_weight += kHugeBump; 190cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org break; 191cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org case MD_ACCESS_VIOLATION_WIN_EXEC: 192cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org if (near_null) 193cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org exploitability_weight += kSmallBump; 194cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org else 195cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org exploitability_weight += kHugeBump; 196cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org break; 197cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org default: 1982b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org BPLOG(INFO) << "Unrecognized access violation type."; 199cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org return EXPLOITABILITY_ERR_PROCESSING; 200cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org break; 201cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org } 2022b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org MinidumpMemoryRegion *instruction_region = 0; 2038b2e6865e54d52fcd45514e12e90ee425b82cb52cdn@chromium.org if (memory_available) { 2048b2e6865e54d52fcd45514e12e90ee425b82cb52cdn@chromium.org instruction_region = 2058b2e6865e54d52fcd45514e12e90ee425b82cb52cdn@chromium.org memory_list->GetMemoryRegionForAddress(instruction_ptr); 2068b2e6865e54d52fcd45514e12e90ee425b82cb52cdn@chromium.org } 2072b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org if (!near_null && instruction_region && 2082b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org context->GetContextCPU() == MD_CONTEXT_X86 && 2092b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org (bad_read || bad_write)) { 2102b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org // Perform checks related to memory around instruction pointer. 2116162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint32_t memory_offset = 2128b2e6865e54d52fcd45514e12e90ee425b82cb52cdn@chromium.org instruction_ptr - instruction_region->GetBase(); 2136162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint32_t available_memory = 2148b2e6865e54d52fcd45514e12e90ee425b82cb52cdn@chromium.org instruction_region->GetSize() - memory_offset; 2152b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org available_memory = available_memory > kDisassembleBytesBeyondPC ? 2162b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org kDisassembleBytesBeyondPC : available_memory; 2172b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org if (available_memory) { 2186162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com const uint8_t *raw_memory = 2198b2e6865e54d52fcd45514e12e90ee425b82cb52cdn@chromium.org instruction_region->GetMemory() + memory_offset; 2208b2e6865e54d52fcd45514e12e90ee425b82cb52cdn@chromium.org DisassemblerX86 disassembler(raw_memory, 2218b2e6865e54d52fcd45514e12e90ee425b82cb52cdn@chromium.org available_memory, 2228b2e6865e54d52fcd45514e12e90ee425b82cb52cdn@chromium.org instruction_ptr); 2232b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org disassembler.NextInstruction(); 2242b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org if (bad_read) 2252b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org disassembler.setBadRead(); 2262b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org else 2272b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org disassembler.setBadWrite(); 2282b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org if (disassembler.currentInstructionValid()) { 2292b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org // Check if the faulting instruction falls into one of 2302b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org // several interesting groups. 2312b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org switch (disassembler.currentInstructionGroup()) { 2322b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org case libdis::insn_controlflow: 2332b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org exploitability_weight += kLargeBump; 2342b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org break; 2352b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org case libdis::insn_string: 2362b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org exploitability_weight += kHugeBump; 2372b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org break; 238361f24eac7fb452a795709479fc48fd59b04bc1fSiyangXie@gmail.com default: 239361f24eac7fb452a795709479fc48fd59b04bc1fSiyangXie@gmail.com break; 2402b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org } 2412b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org // Loop the disassembler through the code and check if it 2422b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org // IDed any interesting conditions in the near future. 2432b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org // Multiple flags may be set so treat each equally. 2442b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org while (disassembler.NextInstruction() && 2452b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org disassembler.currentInstructionValid() && 2462b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org !disassembler.endOfBlock()) 2472b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org continue; 2482b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org if (disassembler.flags() & DISX86_BAD_BRANCH_TARGET) 2492b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org exploitability_weight += kLargeBump; 2502b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org if (disassembler.flags() & DISX86_BAD_ARGUMENT_PASSED) 2512b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org exploitability_weight += kTinyBump; 2522b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org if (disassembler.flags() & DISX86_BAD_WRITE) 2532b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org exploitability_weight += kMediumBump; 2542b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org if (disassembler.flags() & DISX86_BAD_BLOCK_WRITE) 2552b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org exploitability_weight += kMediumBump; 2562b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org if (disassembler.flags() & DISX86_BAD_READ) 2572b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org exploitability_weight += kTinyBump; 2582b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org if (disassembler.flags() & DISX86_BAD_BLOCK_READ) 2592b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org exploitability_weight += kTinyBump; 2602b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org if (disassembler.flags() & DISX86_BAD_COMPARISON) 2612b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org exploitability_weight += kTinyBump; 2622b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org } 2632b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org } 2642b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org } 2658b2e6865e54d52fcd45514e12e90ee425b82cb52cdn@chromium.org if (!near_null && AddressIsAscii(address)) 2668b2e6865e54d52fcd45514e12e90ee425b82cb52cdn@chromium.org exploitability_weight += kMediumBump; 267cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org } else { 2682b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org BPLOG(INFO) << "Access violation type parameter missing."; 269cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org return EXPLOITABILITY_ERR_PROCESSING; 270cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org } 271cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org } 272cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org 273cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org // Based on the calculated weight we return a simplified classification. 2742b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org BPLOG(INFO) << "Calculated exploitability weight: " << exploitability_weight; 2752b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org if (exploitability_weight >= kHighCutoff) 276cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org return EXPLOITABILITY_HIGH; 2772b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org if (exploitability_weight >= kMediumCutoff) 278cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org return EXPLOITABLITY_MEDIUM; 2792b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org if (exploitability_weight >= kLowCutoff) 280cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org return EXPLOITABILITY_LOW; 2812b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org if (exploitability_weight >= kInterestingCutoff) 282cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org return EXPLOITABILITY_INTERESTING; 283cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org 284cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org return EXPLOITABILITY_NONE; 285cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org} 286cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org 287cec12872c403314261e151cf2fa4505ae1affaf6cdn@chromium.org} // namespace google_breakpad 288