From 8b2e6865e54d52fcd45514e12e90ee425b82cb52 Mon Sep 17 00:00:00 2001 From: "cdn@chromium.org" Date: Fri, 1 Oct 2010 23:25:48 +0000 Subject: Added method to exploitability class which checks if a given address contains all ascii characters. BUG=NONE TEST=ExploitabilityTest.TestWindowsEngine Review URL: http://breakpad.appspot.com/207001 git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@706 4c0a9323-5329-0410-9bdc-e9ce6186880e --- src/google_breakpad/processor/exploitability.h | 1 + src/processor/exploitability.cc | 10 +++++ src/processor/exploitability_unittest.cc | 62 +++++++++++++++++++------- src/processor/exploitability_win.cc | 21 ++++++--- 4 files changed, 71 insertions(+), 23 deletions(-) (limited to 'src') diff --git a/src/google_breakpad/processor/exploitability.h b/src/google_breakpad/processor/exploitability.h index 24eed82e..225206d7 100644 --- a/src/google_breakpad/processor/exploitability.h +++ b/src/google_breakpad/processor/exploitability.h @@ -54,6 +54,7 @@ class Exploitability { ProcessState *process_state); ExploitabilityRating CheckExploitability(); + bool AddressIsAscii(u_int64_t); protected: Exploitability(Minidump *dump, diff --git a/src/processor/exploitability.cc b/src/processor/exploitability.cc index fc015201..d8821d4b 100644 --- a/src/processor/exploitability.cc +++ b/src/processor/exploitability.cc @@ -90,5 +90,15 @@ Exploitability *Exploitability::ExploitabilityForPlatform( return platform_exploitability; } +bool Exploitability::AddressIsAscii(u_int64_t address) { + for (int i = 0; i < 8; i++) { + u_int8_t byte = (address >> (8*i)) & 0xff; + if ((byte >= ' ' && byte <= '~') || byte == 0) + continue; + return false; + } + return true; +} + } // namespace google_breakpad diff --git a/src/processor/exploitability_unittest.cc b/src/processor/exploitability_unittest.cc index fab4b448..d365e610 100644 --- a/src/processor/exploitability_unittest.cc +++ b/src/processor/exploitability_unittest.cc @@ -127,87 +127,115 @@ TEST(ExploitabilityTest, TestWindowsEngine) { ProcessState state; string minidump_file = string(getenv("srcdir") ? getenv("srcdir") : ".") + - "/src/processor/testdata/ascii_read_av.dmp"; + "/src/processor/testdata/ascii_read_av.dmp"; ASSERT_EQ(processor.Process(minidump_file, &state), google_breakpad::PROCESS_OK); - ASSERT_EQ(google_breakpad::EXPLOITABILITY_LOW, + ASSERT_EQ(google_breakpad::EXPLOITABILITY_HIGH, state.exploitability()); minidump_file = string(getenv("srcdir") ? getenv("srcdir") : ".") + - "/src/processor/testdata/ascii_read_av_block_write.dmp"; + "/src/processor/testdata/ascii_read_av_block_write.dmp"; ASSERT_EQ(processor.Process(minidump_file, &state), google_breakpad::PROCESS_OK); ASSERT_EQ(google_breakpad::EXPLOITABILITY_HIGH, state.exploitability()); minidump_file = string(getenv("srcdir") ? getenv("srcdir") : ".") + - "/src/processor/testdata/ascii_read_av_clobber_write.dmp"; + "/src/processor/testdata/ascii_read_av_clobber_write.dmp"; ASSERT_EQ(processor.Process(minidump_file, &state), google_breakpad::PROCESS_OK); - ASSERT_EQ(google_breakpad::EXPLOITABILITY_LOW, + ASSERT_EQ(google_breakpad::EXPLOITABILITY_HIGH, state.exploitability()); minidump_file = string(getenv("srcdir") ? getenv("srcdir") : ".") + - "/src/processor/testdata/ascii_read_av_conditional.dmp"; + "/src/processor/testdata/ascii_read_av_conditional.dmp"; ASSERT_EQ(processor.Process(minidump_file, &state), google_breakpad::PROCESS_OK); - ASSERT_EQ(google_breakpad::EXPLOITABILITY_LOW, + ASSERT_EQ(google_breakpad::EXPLOITABILITY_HIGH, state.exploitability()); minidump_file = string(getenv("srcdir") ? getenv("srcdir") : ".") + - "/src/processor/testdata/ascii_read_av_then_jmp.dmp"; + "/src/processor/testdata/ascii_read_av_then_jmp.dmp"; ASSERT_EQ(processor.Process(minidump_file, &state), google_breakpad::PROCESS_OK); ASSERT_EQ(google_breakpad::EXPLOITABILITY_HIGH, state.exploitability()); minidump_file = string(getenv("srcdir") ? getenv("srcdir") : ".") + - "/src/processor/testdata/ascii_read_av_xchg_write.dmp"; + "/src/processor/testdata/ascii_read_av_xchg_write.dmp"; ASSERT_EQ(processor.Process(minidump_file, &state), google_breakpad::PROCESS_OK); ASSERT_EQ(google_breakpad::EXPLOITABILITY_HIGH, state.exploitability()); minidump_file = string(getenv("srcdir") ? getenv("srcdir") : ".") + - "/src/processor/testdata/ascii_write_av.dmp"; + "/src/processor/testdata/ascii_write_av.dmp"; ASSERT_EQ(processor.Process(minidump_file, &state), google_breakpad::PROCESS_OK); - ASSERT_EQ(google_breakpad::EXPLOITABLITY_MEDIUM, + ASSERT_EQ(google_breakpad::EXPLOITABILITY_HIGH, state.exploitability()); minidump_file = string(getenv("srcdir") ? getenv("srcdir") : ".") + - "/src/processor/testdata/ascii_write_av_arg_to_call.dmp"; + "/src/processor/testdata/ascii_write_av_arg_to_call.dmp"; ASSERT_EQ(processor.Process(minidump_file, &state), google_breakpad::PROCESS_OK); - ASSERT_EQ(google_breakpad::EXPLOITABLITY_MEDIUM, + ASSERT_EQ(google_breakpad::EXPLOITABILITY_HIGH, state.exploitability()); minidump_file = string(getenv("srcdir") ? getenv("srcdir") : ".") + - "/src/processor/testdata/null_read_av.dmp"; + "/src/processor/testdata/null_read_av.dmp"; ASSERT_EQ(processor.Process(minidump_file, &state), google_breakpad::PROCESS_OK); ASSERT_EQ(google_breakpad::EXPLOITABILITY_NONE, state.exploitability()); minidump_file = string(getenv("srcdir") ? getenv("srcdir") : ".") + - "/src/processor/testdata/null_write_av.dmp"; + "/src/processor/testdata/null_write_av.dmp"; ASSERT_EQ(processor.Process(minidump_file, &state), google_breakpad::PROCESS_OK); ASSERT_EQ(google_breakpad::EXPLOITABILITY_NONE, state.exploitability()); minidump_file = string(getenv("srcdir") ? getenv("srcdir") : ".") + - "/src/processor/testdata/stack_exhaustion.dmp"; + "/src/processor/testdata/stack_exhaustion.dmp"; ASSERT_EQ(processor.Process(minidump_file, &state), google_breakpad::PROCESS_OK); ASSERT_EQ(google_breakpad::EXPLOITABILITY_NONE, state.exploitability()); minidump_file = string(getenv("srcdir") ? getenv("srcdir") : ".") + - "/src/processor/testdata/exec_av_on_stack.dmp"; + "/src/processor/testdata/exec_av_on_stack.dmp"; ASSERT_EQ(processor.Process(minidump_file, &state), google_breakpad::PROCESS_OK); ASSERT_EQ(google_breakpad::EXPLOITABILITY_HIGH, state.exploitability()); + + minidump_file = string(getenv("srcdir") ? getenv("srcdir") : ".") + + "/src/processor/testdata/write_av_non_null.dmp"; + ASSERT_EQ(processor.Process(minidump_file, &state), + google_breakpad::PROCESS_OK); + ASSERT_EQ(google_breakpad::EXPLOITABLITY_MEDIUM, + state.exploitability()); + + minidump_file = string(getenv("srcdir") ? getenv("srcdir") : ".") + + "/src/processor/testdata/read_av_non_null.dmp"; + ASSERT_EQ(processor.Process(minidump_file, &state), + google_breakpad::PROCESS_OK); + ASSERT_EQ(google_breakpad::EXPLOITABILITY_LOW, + state.exploitability()); + + minidump_file = string(getenv("srcdir") ? getenv("srcdir") : ".") + + "/src/processor/testdata/read_av_clobber_write.dmp"; + ASSERT_EQ(processor.Process(minidump_file, &state), + google_breakpad::PROCESS_OK); + ASSERT_EQ(google_breakpad::EXPLOITABILITY_LOW, + state.exploitability()); + + minidump_file = string(getenv("srcdir") ? getenv("srcdir") : ".") + + "/src/processor/testdata/read_av_conditional.dmp"; + ASSERT_EQ(processor.Process(minidump_file, &state), + google_breakpad::PROCESS_OK); + ASSERT_EQ(google_breakpad::EXPLOITABILITY_LOW, + state.exploitability()); } } diff --git a/src/processor/exploitability_win.cc b/src/processor/exploitability_win.cc index 3d5a9195..9837b791 100644 --- a/src/processor/exploitability_win.cc +++ b/src/processor/exploitability_win.cc @@ -204,19 +204,26 @@ ExploitabilityRating ExploitabilityWin::CheckPlatformExploitability() { break; } MinidumpMemoryRegion *instruction_region = 0; - if (memory_available) - instruction_region = memory_list->GetMemoryRegionForAddress(instruction_ptr); + 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. - u_int32_t memory_offset = instruction_ptr - instruction_region->GetBase(); - u_int32_t available_memory = instruction_region->GetSize() - memory_offset; + u_int32_t memory_offset = + instruction_ptr - instruction_region->GetBase(); + u_int32_t available_memory = + instruction_region->GetSize() - memory_offset; available_memory = available_memory > kDisassembleBytesBeyondPC ? kDisassembleBytesBeyondPC : available_memory; if (available_memory) { - const u_int8_t *raw_memory = instruction_region->GetMemory() + memory_offset; - DisassemblerX86 disassembler(raw_memory, available_memory, instruction_ptr); + const u_int8_t *raw_memory = + instruction_region->GetMemory() + memory_offset; + DisassemblerX86 disassembler(raw_memory, + available_memory, + instruction_ptr); disassembler.NextInstruction(); if (bad_read) disassembler.setBadRead(); @@ -257,6 +264,8 @@ ExploitabilityRating ExploitabilityWin::CheckPlatformExploitability() { } } } + if (!near_null && AddressIsAscii(address)) + exploitability_weight += kMediumBump; } else { BPLOG(INFO) << "Access violation type parameter missing."; return EXPLOITABILITY_ERR_PROCESSING; -- cgit v1.2.1