| Index: src/processor/exploitability_unittest.cc
|
| ===================================================================
|
| --- src/processor/exploitability_unittest.cc (revision 1491)
|
| +++ src/processor/exploitability_unittest.cc (working copy)
|
| @@ -37,11 +37,41 @@
|
| #include "google_breakpad/processor/basic_source_line_resolver.h"
|
| #include "google_breakpad/processor/minidump_processor.h"
|
| #include "google_breakpad/processor/process_state.h"
|
| +#ifndef _WIN32
|
| +#include "processor/exploitability_linux.h"
|
| +#endif // _WIN32
|
| #include "processor/simple_symbol_supplier.h"
|
|
|
| +#ifndef _WIN32
|
| +namespace google_breakpad {
|
| +
|
| +class ExploitabilityLinuxTest : public ExploitabilityLinux {
|
| + public:
|
| + using ExploitabilityLinux::DisassembleBytes;
|
| + using ExploitabilityLinux::TokenizeObjdumpInstruction;
|
| + using ExploitabilityLinux::CalculateAddress;
|
| +};
|
| +
|
| +class ExploitabilityLinuxTestMinidumpContext : public MinidumpContext {
|
| + public:
|
| + explicit ExploitabilityLinuxTestMinidumpContext(
|
| + const MDRawContextAMD64& context) : MinidumpContext(NULL) {
|
| + valid_ = true;
|
| + SetContextAMD64(new MDRawContextAMD64(context));
|
| + SetContextFlags(MD_CONTEXT_AMD64);
|
| + }
|
| +};
|
| +
|
| +} // namespace google_breakpad
|
| +#endif // _WIN32
|
| +
|
| namespace {
|
|
|
| using google_breakpad::BasicSourceLineResolver;
|
| +#ifndef _WIN32
|
| +using google_breakpad::ExploitabilityLinuxTest;
|
| +using google_breakpad::ExploitabilityLinuxTestMinidumpContext;
|
| +#endif // _WIN32
|
| using google_breakpad::MinidumpProcessor;
|
| using google_breakpad::ProcessState;
|
| using google_breakpad::SimpleSymbolSupplier;
|
| @@ -59,6 +89,7 @@
|
| SimpleSymbolSupplier supplier(TestDataDir() + "/symbols");
|
| BasicSourceLineResolver resolver;
|
| MinidumpProcessor processor(&supplier, &resolver, true);
|
| + processor.set_enable_objdump(true);
|
| ProcessState state;
|
|
|
| string minidump_file = TestDataDir() + "/" + filename;
|
| @@ -135,6 +166,95 @@
|
| ExploitabilityFor("linux_executable_stack.dmp"));
|
| ASSERT_EQ(google_breakpad::EXPLOITABILITY_HIGH,
|
| ExploitabilityFor("linux_executable_heap.dmp"));
|
| + ASSERT_EQ(google_breakpad::EXPLOITABILITY_HIGH,
|
| + ExploitabilityFor("linux_jmp_to_module_not_exe_region.dmp"));
|
| +#ifndef _WIN32
|
| + ASSERT_EQ(google_breakpad::EXPLOITABILITY_HIGH,
|
| + ExploitabilityFor("linux_write_to_nonwritable_module.dmp"));
|
| + ASSERT_EQ(google_breakpad::EXPLOITABILITY_HIGH,
|
| + ExploitabilityFor("linux_write_to_nonwritable_region_math.dmp"));
|
| + ASSERT_EQ(google_breakpad::EXPLOITABILITY_HIGH,
|
| + ExploitabilityFor("linux_write_to_outside_module.dmp"));
|
| + ASSERT_EQ(google_breakpad::EXPLOITABILITY_HIGH,
|
| + ExploitabilityFor("linux_write_to_outside_module_via_math.dmp"));
|
| + ASSERT_EQ(google_breakpad::EXPLOITABILITY_INTERESTING,
|
| + ExploitabilityFor("linux_write_to_under_4k.dmp"));
|
| +#endif // _WIN32
|
| +}
|
|
|
| +#ifndef _WIN32
|
| +TEST(ExploitabilityLinuxUtilsTest, DisassembleBytesTest) {
|
| + ASSERT_FALSE(ExploitabilityLinuxTest::DisassembleBytes("", NULL, 5, NULL));
|
| + uint8_t bytes[6] = {0xc7, 0x0, 0x5, 0x0, 0x0, 0x0};
|
| + char buffer[1024] = {0};
|
| + ASSERT_TRUE(ExploitabilityLinuxTest::DisassembleBytes("i386:x86-64",
|
| + bytes,
|
| + 1024,
|
| + buffer));
|
| + std::stringstream objdump_stream;
|
| + objdump_stream.str(string(buffer));
|
| + string line = "";
|
| + while ((line.find("0:") == string::npos) && getline(objdump_stream, line)) {
|
| + }
|
| + ASSERT_EQ(line, " 0:\tc7 00 05 00 00 00 \tmov DWORD PTR [rax],0x5");
|
| }
|
| +
|
| +TEST(ExploitabilityLinuxUtilsTest, TokenizeObjdumpInstructionTest) {
|
| + ASSERT_FALSE(ExploitabilityLinuxTest::TokenizeObjdumpInstruction("",
|
| + NULL,
|
| + NULL,
|
| + NULL));
|
| + string line = "0: c7 00 05 00 00 00 mov DWORD PTR [rax],0x5";
|
| + string operation = "";
|
| + string dest = "";
|
| + string src = "";
|
| + ASSERT_TRUE(ExploitabilityLinuxTest::TokenizeObjdumpInstruction(line,
|
| + &operation,
|
| + &dest,
|
| + &src));
|
| + ASSERT_EQ(operation, "mov");
|
| + ASSERT_EQ(dest, "[rax]");
|
| + ASSERT_EQ(src, "0x5");
|
| + line = "0: c3 ret";
|
| + ASSERT_TRUE(ExploitabilityLinuxTest::TokenizeObjdumpInstruction(line,
|
| + &operation,
|
| + &dest,
|
| + &src));
|
| + ASSERT_EQ(operation, "ret");
|
| + ASSERT_EQ(dest, "");
|
| + ASSERT_EQ(src, "");
|
| + line = "0: 5f pop rdi";
|
| + ASSERT_TRUE(ExploitabilityLinuxTest::TokenizeObjdumpInstruction(line,
|
| + &operation,
|
| + &dest,
|
| + &src));
|
| + ASSERT_EQ(operation, "pop");
|
| + ASSERT_EQ(dest, "rdi");
|
| + ASSERT_EQ(src, "");
|
| }
|
| +
|
| +TEST(ExploitabilityLinuxUtilsTest, CalculateAddressTest) {
|
| + MDRawContextAMD64 raw_context;
|
| + raw_context.rdx = 12345;
|
| + ExploitabilityLinuxTestMinidumpContext context(raw_context);
|
| + ASSERT_EQ(context.GetContextAMD64()->rdx, 12345);
|
| + ASSERT_FALSE(ExploitabilityLinuxTest::CalculateAddress("", context, NULL));
|
| + uint64_t write_address = 0;
|
| + ASSERT_TRUE(ExploitabilityLinuxTest::CalculateAddress("rdx-0x4D2",
|
| + context,
|
| + &write_address));
|
| + ASSERT_EQ(write_address, 11111);
|
| + ASSERT_TRUE(ExploitabilityLinuxTest::CalculateAddress("rdx+0x4D2",
|
| + context,
|
| + &write_address));
|
| + ASSERT_EQ(write_address, 13579);
|
| + ASSERT_FALSE(ExploitabilityLinuxTest::CalculateAddress("rdx+rax",
|
| + context,
|
| + &write_address));
|
| + ASSERT_FALSE(ExploitabilityLinuxTest::CalculateAddress("0x3482+0x4D2",
|
| + context,
|
| + &write_address));
|
| +}
|
| +#endif // _WIN32
|
| +
|
| +} // namespace
|
|
|