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
This commit is contained in:
cdn@chromium.org 2010-10-01 23:25:48 +00:00
parent 2b4274afc4
commit 8b2e6865e5
4 changed files with 99 additions and 51 deletions

View file

@ -54,6 +54,7 @@ class Exploitability {
ProcessState *process_state); ProcessState *process_state);
ExploitabilityRating CheckExploitability(); ExploitabilityRating CheckExploitability();
bool AddressIsAscii(u_int64_t);
protected: protected:
Exploitability(Minidump *dump, Exploitability(Minidump *dump,

View file

@ -90,5 +90,15 @@ Exploitability *Exploitability::ExploitabilityForPlatform(
return platform_exploitability; 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 } // namespace google_breakpad

View file

@ -130,7 +130,7 @@ TEST(ExploitabilityTest, TestWindowsEngine) {
"/src/processor/testdata/ascii_read_av.dmp"; "/src/processor/testdata/ascii_read_av.dmp";
ASSERT_EQ(processor.Process(minidump_file, &state), ASSERT_EQ(processor.Process(minidump_file, &state),
google_breakpad::PROCESS_OK); google_breakpad::PROCESS_OK);
ASSERT_EQ(google_breakpad::EXPLOITABILITY_LOW, ASSERT_EQ(google_breakpad::EXPLOITABILITY_HIGH,
state.exploitability()); state.exploitability());
minidump_file = string(getenv("srcdir") ? getenv("srcdir") : ".") + minidump_file = string(getenv("srcdir") ? getenv("srcdir") : ".") +
@ -144,14 +144,14 @@ TEST(ExploitabilityTest, TestWindowsEngine) {
"/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), ASSERT_EQ(processor.Process(minidump_file, &state),
google_breakpad::PROCESS_OK); google_breakpad::PROCESS_OK);
ASSERT_EQ(google_breakpad::EXPLOITABILITY_LOW, ASSERT_EQ(google_breakpad::EXPLOITABILITY_HIGH,
state.exploitability()); state.exploitability());
minidump_file = string(getenv("srcdir") ? getenv("srcdir") : ".") + 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), ASSERT_EQ(processor.Process(minidump_file, &state),
google_breakpad::PROCESS_OK); google_breakpad::PROCESS_OK);
ASSERT_EQ(google_breakpad::EXPLOITABILITY_LOW, ASSERT_EQ(google_breakpad::EXPLOITABILITY_HIGH,
state.exploitability()); state.exploitability());
minidump_file = string(getenv("srcdir") ? getenv("srcdir") : ".") + minidump_file = string(getenv("srcdir") ? getenv("srcdir") : ".") +
@ -172,14 +172,14 @@ TEST(ExploitabilityTest, TestWindowsEngine) {
"/src/processor/testdata/ascii_write_av.dmp"; "/src/processor/testdata/ascii_write_av.dmp";
ASSERT_EQ(processor.Process(minidump_file, &state), ASSERT_EQ(processor.Process(minidump_file, &state),
google_breakpad::PROCESS_OK); google_breakpad::PROCESS_OK);
ASSERT_EQ(google_breakpad::EXPLOITABLITY_MEDIUM, ASSERT_EQ(google_breakpad::EXPLOITABILITY_HIGH,
state.exploitability()); state.exploitability());
minidump_file = string(getenv("srcdir") ? getenv("srcdir") : ".") + 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), ASSERT_EQ(processor.Process(minidump_file, &state),
google_breakpad::PROCESS_OK); google_breakpad::PROCESS_OK);
ASSERT_EQ(google_breakpad::EXPLOITABLITY_MEDIUM, ASSERT_EQ(google_breakpad::EXPLOITABILITY_HIGH,
state.exploitability()); state.exploitability());
minidump_file = string(getenv("srcdir") ? getenv("srcdir") : ".") + minidump_file = string(getenv("srcdir") ? getenv("srcdir") : ".") +
@ -209,5 +209,33 @@ TEST(ExploitabilityTest, TestWindowsEngine) {
google_breakpad::PROCESS_OK); google_breakpad::PROCESS_OK);
ASSERT_EQ(google_breakpad::EXPLOITABILITY_HIGH, ASSERT_EQ(google_breakpad::EXPLOITABILITY_HIGH,
state.exploitability()); 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());
} }
} }

View file

@ -204,19 +204,26 @@ ExploitabilityRating ExploitabilityWin::CheckPlatformExploitability() {
break; break;
} }
MinidumpMemoryRegion *instruction_region = 0; MinidumpMemoryRegion *instruction_region = 0;
if (memory_available) if (memory_available) {
instruction_region = memory_list->GetMemoryRegionForAddress(instruction_ptr); instruction_region =
memory_list->GetMemoryRegionForAddress(instruction_ptr);
}
if (!near_null && instruction_region && if (!near_null && instruction_region &&
context->GetContextCPU() == MD_CONTEXT_X86 && context->GetContextCPU() == MD_CONTEXT_X86 &&
(bad_read || bad_write)) { (bad_read || bad_write)) {
// Perform checks related to memory around instruction pointer. // Perform checks related to memory around instruction pointer.
u_int32_t memory_offset = instruction_ptr - instruction_region->GetBase(); u_int32_t memory_offset =
u_int32_t available_memory = instruction_region->GetSize() - memory_offset; instruction_ptr - instruction_region->GetBase();
u_int32_t available_memory =
instruction_region->GetSize() - memory_offset;
available_memory = available_memory > kDisassembleBytesBeyondPC ? available_memory = available_memory > kDisassembleBytesBeyondPC ?
kDisassembleBytesBeyondPC : available_memory; kDisassembleBytesBeyondPC : available_memory;
if (available_memory) { if (available_memory) {
const u_int8_t *raw_memory = instruction_region->GetMemory() + memory_offset; const u_int8_t *raw_memory =
DisassemblerX86 disassembler(raw_memory, available_memory, instruction_ptr); instruction_region->GetMemory() + memory_offset;
DisassemblerX86 disassembler(raw_memory,
available_memory,
instruction_ptr);
disassembler.NextInstruction(); disassembler.NextInstruction();
if (bad_read) if (bad_read)
disassembler.setBadRead(); disassembler.setBadRead();
@ -257,6 +264,8 @@ ExploitabilityRating ExploitabilityWin::CheckPlatformExploitability() {
} }
} }
} }
if (!near_null && AddressIsAscii(address))
exploitability_weight += kMediumBump;
} else { } else {
BPLOG(INFO) << "Access violation type parameter missing."; BPLOG(INFO) << "Access violation type parameter missing.";
return EXPLOITABILITY_ERR_PROCESSING; return EXPLOITABILITY_ERR_PROCESSING;