Added the base exploitability module for windows. This only adds the very basic exception type based analysis for now.

BUG=NONE
TEST=MinidumpProcessorTest.TestExploitilityEngine

Review URL: http://breakpad.appspot.com/189001

git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@698 4c0a9323-5329-0410-9bdc-e9ce6186880e
This commit is contained in:
cdn@chromium.org 2010-09-22 02:37:19 +00:00
parent 9a57c16c97
commit cec12872c4
9 changed files with 288 additions and 32 deletions

View file

@ -101,6 +101,8 @@ src_libbreakpad_la_SOURCES = \
src/processor/contained_range_map-inl.h \
src/processor/contained_range_map.h \
src/processor/exploitability.cc \
src/processor/exploitability_win.h \
src/processor/exploitability_win.cc \
src/processor/linked_ptr.h \
src/processor/logging.h \
src/processor/logging.cc \
@ -304,6 +306,7 @@ src_processor_minidump_processor_unittest_LDADD = \
src/processor/call_stack.lo \
src/processor/cfi_frame_info.lo \
src/processor/exploitability.lo \
src/processor/exploitability_win.lo \
src/processor/logging.lo \
src/processor/minidump_processor.lo \
src/processor/minidump.lo \
@ -370,6 +373,7 @@ src_processor_network_source_line_resolver_server_unittest_LDADD = \
src/processor/call_stack.lo \
src/processor/cfi_frame_info.lo \
src/processor/exploitability.lo \
src/processor/exploitability_win.lo \
src/processor/logging.lo \
src/processor/minidump_processor.lo \
src/processor/minidump.lo \
@ -441,6 +445,7 @@ src_processor_stackwalker_selftest_LDADD = \
src/processor/basic_source_line_resolver.lo \
src/processor/call_stack.lo \
src/processor/exploitability.lo \
src/processor/exploitability_win.lo \
src/processor/logging.lo \
src/processor/minidump.lo \
src/processor/pathname_stripper.lo \
@ -543,6 +548,7 @@ src_processor_minidump_stackwalk_LDADD = \
src/processor/call_stack.lo \
src/processor/cfi_frame_info.lo \
src/processor/exploitability.lo \
src/processor/exploitability_win.lo \
src/processor/logging.lo \
src/processor/minidump.lo \
src/processor/minidump_processor.lo \

View file

@ -172,7 +172,8 @@ am_src_libbreakpad_la_OBJECTS = src/processor/basic_code_modules.lo \
src/processor/basic_source_line_resolver.lo \
src/processor/binarystream.lo src/processor/call_stack.lo \
src/processor/cfi_frame_info.lo \
src/processor/exploitability.lo src/processor/logging.lo \
src/processor/exploitability.lo \
src/processor/exploitability_win.lo src/processor/logging.lo \
src/processor/minidump.lo src/processor/minidump_processor.lo \
src/processor/network_source_line_resolver.lo \
src/processor/network_source_line_server.lo \
@ -284,7 +285,8 @@ src_processor_minidump_processor_unittest_DEPENDENCIES = \
src/processor/basic_code_modules.lo \
src/processor/basic_source_line_resolver.lo \
src/processor/call_stack.lo src/processor/cfi_frame_info.lo \
src/processor/exploitability.lo src/processor/logging.lo \
src/processor/exploitability.lo \
src/processor/exploitability_win.lo src/processor/logging.lo \
src/processor/minidump_processor.lo src/processor/minidump.lo \
src/processor/pathname_stripper.lo \
src/processor/process_state.lo src/processor/stackwalker.lo \
@ -302,7 +304,8 @@ src_processor_minidump_stackwalk_DEPENDENCIES = \
src/processor/basic_source_line_resolver.lo \
src/processor/binarystream.lo src/processor/call_stack.lo \
src/processor/cfi_frame_info.lo \
src/processor/exploitability.lo src/processor/logging.lo \
src/processor/exploitability.lo \
src/processor/exploitability_win.lo src/processor/logging.lo \
src/processor/minidump.lo src/processor/minidump_processor.lo \
src/processor/pathname_stripper.lo \
src/processor/process_state.lo \
@ -335,7 +338,8 @@ src_processor_network_source_line_resolver_server_unittest_DEPENDENCIES = \
src/processor/basic_source_line_resolver.lo \
src/processor/binarystream.lo src/processor/call_stack.lo \
src/processor/cfi_frame_info.lo \
src/processor/exploitability.lo src/processor/logging.lo \
src/processor/exploitability.lo \
src/processor/exploitability_win.lo src/processor/logging.lo \
src/processor/minidump_processor.lo src/processor/minidump.lo \
src/processor/network_source_line_resolver.lo \
src/processor/network_source_line_server.lo \
@ -427,8 +431,8 @@ src_processor_stackwalker_selftest_DEPENDENCIES = \
src/processor/basic_code_modules.lo \
src/processor/basic_source_line_resolver.lo \
src/processor/call_stack.lo src/processor/exploitability.lo \
src/processor/logging.lo src/processor/minidump.lo \
src/processor/pathname_stripper.lo \
src/processor/exploitability_win.lo src/processor/logging.lo \
src/processor/minidump.lo src/processor/pathname_stripper.lo \
src/processor/stackwalker.lo \
src/processor/stackwalker_amd64.lo \
src/processor/stackwalker_arm.lo \
@ -736,6 +740,8 @@ src_libbreakpad_la_SOURCES = \
src/processor/contained_range_map-inl.h \
src/processor/contained_range_map.h \
src/processor/exploitability.cc \
src/processor/exploitability_win.h \
src/processor/exploitability_win.cc \
src/processor/linked_ptr.h \
src/processor/logging.h \
src/processor/logging.cc \
@ -902,6 +908,7 @@ src_processor_minidump_processor_unittest_LDADD = \
src/processor/call_stack.lo \
src/processor/cfi_frame_info.lo \
src/processor/exploitability.lo \
src/processor/exploitability_win.lo \
src/processor/logging.lo \
src/processor/minidump_processor.lo \
src/processor/minidump.lo \
@ -974,6 +981,7 @@ src_processor_network_source_line_resolver_server_unittest_LDADD = \
src/processor/call_stack.lo \
src/processor/cfi_frame_info.lo \
src/processor/exploitability.lo \
src/processor/exploitability_win.lo \
src/processor/logging.lo \
src/processor/minidump_processor.lo \
src/processor/minidump.lo \
@ -1053,6 +1061,7 @@ src_processor_stackwalker_selftest_LDADD = \
src/processor/basic_source_line_resolver.lo \
src/processor/call_stack.lo \
src/processor/exploitability.lo \
src/processor/exploitability_win.lo \
src/processor/logging.lo \
src/processor/minidump.lo \
src/processor/pathname_stripper.lo \
@ -1162,6 +1171,7 @@ src_processor_minidump_stackwalk_LDADD = \
src/processor/call_stack.lo \
src/processor/cfi_frame_info.lo \
src/processor/exploitability.lo \
src/processor/exploitability_win.lo \
src/processor/logging.lo \
src/processor/minidump.lo \
src/processor/minidump_processor.lo \
@ -1494,6 +1504,8 @@ src/processor/cfi_frame_info.lo: src/processor/$(am__dirstamp) \
src/processor/$(DEPDIR)/$(am__dirstamp)
src/processor/exploitability.lo: src/processor/$(am__dirstamp) \
src/processor/$(DEPDIR)/$(am__dirstamp)
src/processor/exploitability_win.lo: src/processor/$(am__dirstamp) \
src/processor/$(DEPDIR)/$(am__dirstamp)
src/processor/logging.lo: src/processor/$(am__dirstamp) \
src/processor/$(DEPDIR)/$(am__dirstamp)
src/processor/minidump.lo: src/processor/$(am__dirstamp) \
@ -1955,6 +1967,8 @@ mostlyclean-compile:
-rm -f src/processor/contained_range_map_unittest.$(OBJEXT)
-rm -f src/processor/exploitability.$(OBJEXT)
-rm -f src/processor/exploitability.lo
-rm -f src/processor/exploitability_win.$(OBJEXT)
-rm -f src/processor/exploitability_win.lo
-rm -f src/processor/logging.$(OBJEXT)
-rm -f src/processor/logging.lo
-rm -f src/processor/minidump.$(OBJEXT)
@ -2082,6 +2096,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@src/processor/$(DEPDIR)/cfi_frame_info.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/processor/$(DEPDIR)/contained_range_map_unittest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/processor/$(DEPDIR)/exploitability.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/processor/$(DEPDIR)/exploitability_win.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/processor/$(DEPDIR)/logging.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/processor/$(DEPDIR)/minidump.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/processor/$(DEPDIR)/minidump_dump.Po@am__quote@

View file

@ -105,5 +105,12 @@ typedef enum {
generated by Visual C++ compiler */
} MDExceptionCodeWin;
// These constants are defined in the MSDN documentation of
// the EXCEPTION_RECORD structure.
typedef enum {
MD_ACCESS_VIOLATION_WIN_READ = 0,
MD_ACCESS_VIOLATION_WIN_WRITE = 1,
MD_ACCESS_VIOLATION_WIN_EXEC = 8
} MDAccessViolationTypeWin;
#endif /* GOOGLE_BREAKPAD_COMMON_MINIDUMP_EXCEPTION_WIN32_H__ */

View file

@ -59,12 +59,12 @@ class Exploitability {
Exploitability(Minidump *dump,
ProcessState *process_state);
private:
virtual ExploitabilityRating CheckPlatformExploitability() = 0;
Minidump *dump_;
ProcessState *process_state_;
SystemInfo *system_info_;
private:
virtual ExploitabilityRating CheckPlatformExploitability() = 0;
};
} // namespace google_breakpad

View file

@ -39,6 +39,7 @@
#include "google_breakpad/processor/exploitability.h"
#include "google_breakpad/processor/minidump.h"
#include "google_breakpad/processor/process_state.h"
#include "processor/exploitability_win.h"
#include "processor/logging.h"
#include "processor/scoped_ptr.h"
@ -68,10 +69,14 @@ Exploitability *Exploitability::ExploitabilityForPlatform(
switch (raw_system_info->platform_id) {
case MD_OS_WIN32_NT:
case MD_OS_WIN32_WINDOWS:
case MD_OS_UNIX:
case MD_OS_WIN32_WINDOWS: {
platform_exploitability = new ExploitabilityWin(dump,
process_state);
break;
}
case MD_OS_MAC_OS_X:
case MD_OS_LINUX:
case MD_OS_UNIX:
case MD_OS_SOLARIS:
default: {
platform_exploitability = NULL;

View file

@ -0,0 +1,168 @@
// 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 "processor/exploitability_win.h"
#include "google_breakpad/common/minidump_exception_win32.h"
#include "processor/logging.h"
#include "processor/scoped_ptr.h"
namespace google_breakpad {
// The cutoff that we use to judge if and address is likely an offset
// from null.
static const u_int64_t kProbableNullOffset = 4096;
// The various cutoffs for the different ratings.
static const size_t kHighCutoff = 85;
static const size_t kMediumCutoff = 65;
static const size_t kLowCutoff = 45;
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;
ExploitabilityWin::ExploitabilityWin(Minidump *dump,
ProcessState *process_state)
: Exploitability(dump, process_state) { }
ExploitabilityRating ExploitabilityWin::CheckPlatformExploitability() {
MinidumpException *exception = dump_->GetException();
if (!exception)
return EXPLOITABILITY_ERR_PROCESSING;
const MDRawExceptionStream *raw_exception = exception->exception();
if (!raw_exception)
return EXPLOITABILITY_ERR_PROCESSING;
u_int64_t address = raw_exception->exception_record.exception_address;
u_int32_t exception_code = raw_exception->exception_record.exception_code;
u_int32_t exception_flags = raw_exception->exception_record.exception_flags;
u_int32_t exploitability_weight = 0;
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);
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:
if (near_null)
exploitability_weight += kSmallBump;
else
exploitability_weight += kMediumBump;
break;
case MD_ACCESS_VIOLATION_WIN_WRITE:
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:
return EXPLOITABILITY_ERR_PROCESSING;
break;
}
} else {
return EXPLOITABILITY_ERR_PROCESSING;
}
}
// Based on the calculated weight we return a simplified classification.
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

View file

@ -0,0 +1,55 @@
// 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.h: 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
#ifndef GOOGLE_BREAKPAD_PROCESSOR_EXPLOITABILITY_WIN_H_
#define GOOGLE_BREAKPAD_PROCESSOR_EXPLOITABILITY_WIN_H_
#include "google_breakpad/common/breakpad_types.h"
#include "google_breakpad/processor/exploitability.h"
namespace google_breakpad {
class ExploitabilityWin : public Exploitability {
public:
ExploitabilityWin(Minidump *dump,
ProcessState *process_state);
virtual ExploitabilityRating CheckPlatformExploitability();
};
} // namespace google_breakpad
#endif // GOOGLE_BREAKPAD_PROCESSOR_EXPLOITABILITY_WIN_H_

View file

@ -730,14 +730,17 @@ string MinidumpProcessor::GetCrashReason(Minidump *dump, u_int64_t *address) {
// This information is useful in addition to the code address, which
// will be present in the crash thread's instruction field anyway.
if (raw_exception->exception_record.number_parameters >= 1) {
switch (raw_exception->exception_record.exception_information[0]) {
case 0:
MDAccessViolationTypeWin av_type =
static_cast<MDAccessViolationTypeWin>
(raw_exception->exception_record.exception_information[0]);
switch (av_type) {
case MD_ACCESS_VIOLATION_WIN_READ:
reason = "EXCEPTION_ACCESS_VIOLATION_READ";
break;
case 1:
case MD_ACCESS_VIOLATION_WIN_WRITE:
reason = "EXCEPTION_ACCESS_VIOLATION_WRITE";
break;
case 8:
case MD_ACCESS_VIOLATION_WIN_EXEC:
reason = "EXCEPTION_ACCESS_VIOLATION_EXEC";
break;
default:
@ -1064,8 +1067,7 @@ string MinidumpProcessor::GetCrashReason(Minidump *dump, u_int64_t *address) {
}
// static
string MinidumpProcessor::GetAssertion(Minidump *dump)
{
string MinidumpProcessor::GetAssertion(Minidump *dump) {
MinidumpAssertion *assertion = dump->GetAssertion();
if (!assertion)
return "";

View file

@ -58,10 +58,10 @@ class MockMinidump : public Minidump {
MockMinidump() : Minidump("") {
}
MOCK_METHOD0(Read,bool());
MOCK_METHOD0(Read, bool());
MOCK_CONST_METHOD0(path, string());
MOCK_CONST_METHOD0(header,const MDRawHeader*());
MOCK_METHOD0(GetThreadList,MinidumpThreadList*());
MOCK_CONST_METHOD0(header, const MDRawHeader*());
MOCK_METHOD0(GetThreadList, MinidumpThreadList*());
};
}
@ -179,7 +179,6 @@ class MockSymbolSupplier : public SymbolSupplier {
};
class MinidumpProcessorTest : public ::testing::Test {
};
TEST_F(MinidumpProcessorTest, TestCorruptMinidumps) {
@ -257,9 +256,9 @@ TEST_F(MinidumpProcessorTest, TestExploitilityEngine) {
ASSERT_EQ(processor.Process(minidump_file, &state),
google_breakpad::PROCESS_OK);
// Test that exploitability module correctly fails to supply
// an engine for this platform
ASSERT_EQ(google_breakpad::EXPLOITABILITY_ERR_NOENGINE,
// Test that the supplied dump registers as HIGH. This dump demonstrates
// a write access violation to an address which is not near null.
ASSERT_EQ(google_breakpad::EXPLOITABILITY_HIGH,
state.exploitability());
}
@ -342,8 +341,7 @@ TEST_F(MinidumpProcessorTest, TestBasicProcessing) {
state.Clear();
supplier.set_interrupt(true);
ASSERT_EQ(processor.Process(minidump_file, &state),
google_breakpad::PROCESS_SYMBOL_SUPPLIER_INTERRUPTED
);
google_breakpad::PROCESS_SYMBOL_SUPPLIER_INTERRUPTED);
}
} // namespace