OLD | NEW |
1 // Copyright (c) 2010, Google Inc. | 1 // Copyright (c) 2010, Google Inc. |
2 // All rights reserved. | 2 // All rights reserved. |
3 // | 3 // |
4 // Redistribution and use in source and binary forms, with or without | 4 // Redistribution and use in source and binary forms, with or without |
5 // modification, are permitted provided that the following conditions are | 5 // modification, are permitted provided that the following conditions are |
6 // met: | 6 // met: |
7 // | 7 // |
8 // * Redistributions of source code must retain the above copyright | 8 // * Redistributions of source code must retain the above copyright |
9 // notice, this list of conditions and the following disclaimer. | 9 // notice, this list of conditions and the following disclaimer. |
10 // * Redistributions in binary form must reproduce the above | 10 // * Redistributions in binary form must reproduce the above |
(...skipping 19 matching lines...) Expand all Loading... |
30 #include <stdlib.h> | 30 #include <stdlib.h> |
31 #include <unistd.h> | 31 #include <unistd.h> |
32 | 32 |
33 #include <string> | 33 #include <string> |
34 | 34 |
35 #include "breakpad_googletest_includes.h" | 35 #include "breakpad_googletest_includes.h" |
36 #include "common/using_std_string.h" | 36 #include "common/using_std_string.h" |
37 #include "google_breakpad/processor/basic_source_line_resolver.h" | 37 #include "google_breakpad/processor/basic_source_line_resolver.h" |
38 #include "google_breakpad/processor/minidump_processor.h" | 38 #include "google_breakpad/processor/minidump_processor.h" |
39 #include "google_breakpad/processor/process_state.h" | 39 #include "google_breakpad/processor/process_state.h" |
| 40 #ifndef _WIN32 |
| 41 #include "processor/exploitability_linux.h" |
| 42 #endif // _WIN32 |
40 #include "processor/simple_symbol_supplier.h" | 43 #include "processor/simple_symbol_supplier.h" |
41 | 44 |
| 45 #ifndef _WIN32 |
| 46 namespace google_breakpad { |
| 47 |
| 48 class ExploitabilityLinuxTest : public ExploitabilityLinux { |
| 49 public: |
| 50 using ExploitabilityLinux::DisassembleBytes; |
| 51 using ExploitabilityLinux::TokenizeObjdumpInstruction; |
| 52 using ExploitabilityLinux::CalculateAddress; |
| 53 }; |
| 54 |
| 55 class ExploitabilityLinuxTestMinidumpContext : public MinidumpContext { |
| 56 public: |
| 57 explicit ExploitabilityLinuxTestMinidumpContext( |
| 58 const MDRawContextAMD64& context) : MinidumpContext(NULL) { |
| 59 valid_ = true; |
| 60 SetContextAMD64(new MDRawContextAMD64(context)); |
| 61 SetContextFlags(MD_CONTEXT_AMD64); |
| 62 } |
| 63 }; |
| 64 |
| 65 } // namespace google_breakpad |
| 66 #endif // _WIN32 |
| 67 |
42 namespace { | 68 namespace { |
43 | 69 |
44 using google_breakpad::BasicSourceLineResolver; | 70 using google_breakpad::BasicSourceLineResolver; |
| 71 #ifndef _WIN32 |
| 72 using google_breakpad::ExploitabilityLinuxTest; |
| 73 using google_breakpad::ExploitabilityLinuxTestMinidumpContext; |
| 74 #endif // _WIN32 |
45 using google_breakpad::MinidumpProcessor; | 75 using google_breakpad::MinidumpProcessor; |
46 using google_breakpad::ProcessState; | 76 using google_breakpad::ProcessState; |
47 using google_breakpad::SimpleSymbolSupplier; | 77 using google_breakpad::SimpleSymbolSupplier; |
48 | 78 |
49 string TestDataDir() { | 79 string TestDataDir() { |
50 return string(getenv("srcdir") ? getenv("srcdir") : ".") + | 80 return string(getenv("srcdir") ? getenv("srcdir") : ".") + |
51 "/src/processor/testdata"; | 81 "/src/processor/testdata"; |
52 } | 82 } |
53 | 83 |
54 // Find the given dump file in <srcdir>/src/processor/testdata, process it, | 84 // Find the given dump file in <srcdir>/src/processor/testdata, process it, |
55 // and get the exploitability rating. Returns EXPLOITABILITY_ERR_PROCESSING | 85 // and get the exploitability rating. Returns EXPLOITABILITY_ERR_PROCESSING |
56 // if the crash dump can't be processed. | 86 // if the crash dump can't be processed. |
57 google_breakpad::ExploitabilityRating | 87 google_breakpad::ExploitabilityRating |
58 ExploitabilityFor(const string& filename) { | 88 ExploitabilityFor(const string& filename) { |
59 SimpleSymbolSupplier supplier(TestDataDir() + "/symbols"); | 89 SimpleSymbolSupplier supplier(TestDataDir() + "/symbols"); |
60 BasicSourceLineResolver resolver; | 90 BasicSourceLineResolver resolver; |
61 MinidumpProcessor processor(&supplier, &resolver, true); | 91 MinidumpProcessor processor(&supplier, &resolver, true); |
| 92 processor.set_enable_objdump(true); |
62 ProcessState state; | 93 ProcessState state; |
63 | 94 |
64 string minidump_file = TestDataDir() + "/" + filename; | 95 string minidump_file = TestDataDir() + "/" + filename; |
65 | 96 |
66 if (processor.Process(minidump_file, &state) != | 97 if (processor.Process(minidump_file, &state) != |
67 google_breakpad::PROCESS_OK) { | 98 google_breakpad::PROCESS_OK) { |
68 return google_breakpad::EXPLOITABILITY_ERR_PROCESSING; | 99 return google_breakpad::EXPLOITABILITY_ERR_PROCESSING; |
69 } | 100 } |
70 | 101 |
71 return state.exploitability(); | 102 return state.exploitability(); |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
128 ASSERT_EQ(google_breakpad::EXPLOITABILITY_INTERESTING, | 159 ASSERT_EQ(google_breakpad::EXPLOITABILITY_INTERESTING, |
129 ExploitabilityFor("linux_inside_module_exe_region2.dmp")); | 160 ExploitabilityFor("linux_inside_module_exe_region2.dmp")); |
130 ASSERT_EQ(google_breakpad::EXPLOITABILITY_INTERESTING, | 161 ASSERT_EQ(google_breakpad::EXPLOITABILITY_INTERESTING, |
131 ExploitabilityFor("linux_stack_pointer_in_stack.dmp")); | 162 ExploitabilityFor("linux_stack_pointer_in_stack.dmp")); |
132 ASSERT_EQ(google_breakpad::EXPLOITABILITY_HIGH, | 163 ASSERT_EQ(google_breakpad::EXPLOITABILITY_HIGH, |
133 ExploitabilityFor("linux_stack_pointer_in_module.dmp")); | 164 ExploitabilityFor("linux_stack_pointer_in_module.dmp")); |
134 ASSERT_EQ(google_breakpad::EXPLOITABILITY_HIGH, | 165 ASSERT_EQ(google_breakpad::EXPLOITABILITY_HIGH, |
135 ExploitabilityFor("linux_executable_stack.dmp")); | 166 ExploitabilityFor("linux_executable_stack.dmp")); |
136 ASSERT_EQ(google_breakpad::EXPLOITABILITY_HIGH, | 167 ASSERT_EQ(google_breakpad::EXPLOITABILITY_HIGH, |
137 ExploitabilityFor("linux_executable_heap.dmp")); | 168 ExploitabilityFor("linux_executable_heap.dmp")); |
| 169 ASSERT_EQ(google_breakpad::EXPLOITABILITY_HIGH, |
| 170 ExploitabilityFor("linux_jmp_to_module_not_exe_region.dmp")); |
| 171 #ifndef _WIN32 |
| 172 ASSERT_EQ(google_breakpad::EXPLOITABILITY_HIGH, |
| 173 ExploitabilityFor("linux_write_to_nonwritable_module.dmp")); |
| 174 ASSERT_EQ(google_breakpad::EXPLOITABILITY_HIGH, |
| 175 ExploitabilityFor("linux_write_to_nonwritable_region_math.dmp")); |
| 176 ASSERT_EQ(google_breakpad::EXPLOITABILITY_HIGH, |
| 177 ExploitabilityFor("linux_write_to_outside_module.dmp")); |
| 178 ASSERT_EQ(google_breakpad::EXPLOITABILITY_HIGH, |
| 179 ExploitabilityFor("linux_write_to_outside_module_via_math.dmp")); |
| 180 ASSERT_EQ(google_breakpad::EXPLOITABILITY_INTERESTING, |
| 181 ExploitabilityFor("linux_write_to_under_4k.dmp")); |
| 182 #endif // _WIN32 |
| 183 } |
138 | 184 |
| 185 #ifndef _WIN32 |
| 186 TEST(ExploitabilityLinuxUtilsTest, DisassembleBytesTest) { |
| 187 ASSERT_FALSE(ExploitabilityLinuxTest::DisassembleBytes("", NULL, 5, NULL)); |
| 188 uint8_t bytes[6] = {0xc7, 0x0, 0x5, 0x0, 0x0, 0x0}; |
| 189 char buffer[1024] = {0}; |
| 190 ASSERT_TRUE(ExploitabilityLinuxTest::DisassembleBytes("i386:x86-64", |
| 191 bytes, |
| 192 1024, |
| 193 buffer)); |
| 194 std::stringstream objdump_stream; |
| 195 objdump_stream.str(string(buffer)); |
| 196 string line = ""; |
| 197 while ((line.find("0:") == string::npos) && getline(objdump_stream, line)) { |
| 198 } |
| 199 ASSERT_EQ(line, " 0:\tc7 00 05 00 00 00 \tmov DWORD PTR [rax],0x5"); |
139 } | 200 } |
| 201 |
| 202 TEST(ExploitabilityLinuxUtilsTest, TokenizeObjdumpInstructionTest) { |
| 203 ASSERT_FALSE(ExploitabilityLinuxTest::TokenizeObjdumpInstruction("", |
| 204 NULL, |
| 205 NULL, |
| 206 NULL)); |
| 207 string line = "0: c7 00 05 00 00 00 mov DWORD PTR [rax],0x5"; |
| 208 string operation = ""; |
| 209 string dest = ""; |
| 210 string src = ""; |
| 211 ASSERT_TRUE(ExploitabilityLinuxTest::TokenizeObjdumpInstruction(line, |
| 212 &operation, |
| 213 &dest, |
| 214 &src)); |
| 215 ASSERT_EQ(operation, "mov"); |
| 216 ASSERT_EQ(dest, "[rax]"); |
| 217 ASSERT_EQ(src, "0x5"); |
| 218 line = "0: c3 ret"; |
| 219 ASSERT_TRUE(ExploitabilityLinuxTest::TokenizeObjdumpInstruction(line, |
| 220 &operation, |
| 221 &dest, |
| 222 &src)); |
| 223 ASSERT_EQ(operation, "ret"); |
| 224 ASSERT_EQ(dest, ""); |
| 225 ASSERT_EQ(src, ""); |
| 226 line = "0: 5f pop rdi"; |
| 227 ASSERT_TRUE(ExploitabilityLinuxTest::TokenizeObjdumpInstruction(line, |
| 228 &operation, |
| 229 &dest, |
| 230 &src)); |
| 231 ASSERT_EQ(operation, "pop"); |
| 232 ASSERT_EQ(dest, "rdi"); |
| 233 ASSERT_EQ(src, ""); |
140 } | 234 } |
| 235 |
| 236 TEST(ExploitabilityLinuxUtilsTest, CalculateAddressTest) { |
| 237 MDRawContextAMD64 raw_context; |
| 238 raw_context.rdx = 12345; |
| 239 ExploitabilityLinuxTestMinidumpContext context(raw_context); |
| 240 ASSERT_EQ(context.GetContextAMD64()->rdx, 12345); |
| 241 ASSERT_FALSE(ExploitabilityLinuxTest::CalculateAddress("", context, NULL)); |
| 242 uint64_t write_address = 0; |
| 243 ASSERT_TRUE(ExploitabilityLinuxTest::CalculateAddress("rdx-0x4D2", |
| 244 context, |
| 245 &write_address)); |
| 246 ASSERT_EQ(write_address, 11111); |
| 247 ASSERT_TRUE(ExploitabilityLinuxTest::CalculateAddress("rdx+0x4D2", |
| 248 context, |
| 249 &write_address)); |
| 250 ASSERT_EQ(write_address, 13579); |
| 251 ASSERT_FALSE(ExploitabilityLinuxTest::CalculateAddress("rdx+rax", |
| 252 context, |
| 253 &write_address)); |
| 254 ASSERT_FALSE(ExploitabilityLinuxTest::CalculateAddress("0x3482+0x4D2", |
| 255 context, |
| 256 &write_address)); |
| 257 } |
| 258 #endif // _WIN32 |
| 259 |
| 260 } // namespace |
OLD | NEW |