1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
|
// Copyright (c) 2013 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_linux.h: Linux specific exploitability engine.
//
// Provides a guess at the exploitability of the crash for the Linux
// platform given a minidump and process_state.
//
// Author: Matthew Riley
#ifndef GOOGLE_BREAKPAD_PROCESSOR_EXPLOITABILITY_LINUX_H_
#define GOOGLE_BREAKPAD_PROCESSOR_EXPLOITABILITY_LINUX_H_
#include "google_breakpad/common/breakpad_types.h"
#include "google_breakpad/processor/exploitability.h"
namespace google_breakpad {
class ExploitabilityLinux : public Exploitability {
public:
ExploitabilityLinux(Minidump* dump,
ProcessState* process_state);
// Parameters are the minidump to analyze, the object representing process
// state, and whether to enable objdump disassembly.
// Enabling objdump will allow exploitability analysis to call out to
// objdump for diassembly. It is used to check the identity of the
// instruction that caused the program to crash. If there are any
// portability concerns, this should not be enabled.
ExploitabilityLinux(Minidump* dump,
ProcessState* process_state,
bool enable_objdump);
virtual ExploitabilityRating CheckPlatformExploitability();
private:
friend class ExploitabilityLinuxTest;
// Takes the address of the instruction pointer and returns
// whether the instruction pointer lies in a valid instruction region.
bool InstructionPointerInCode(uint64_t instruction_ptr);
// Checks the exception that triggered the creation of the
// minidump and reports whether the exception suggests no exploitability.
bool BenignCrashTrigger(const MDRawExceptionStream* raw_exception_stream);
// This method checks if the crash occurred during a write to read-only or
// invalid memory. It does so by checking if the instruction at the
// instruction pointer is a write instruction, and if the target of the
// instruction is at a spot in memory that prohibits writes.
bool EndedOnIllegalWrite(uint64_t instruction_ptr);
#ifndef _WIN32
// Disassembles raw bytes via objdump and pipes the output into the provided
// buffer, given the desired architecture, the file from which objdump will
// read, and the buffer length. The method returns whether the disassembly
// was a success, and the caller owns all pointers.
static bool DisassembleBytes(const string& architecture,
const uint8_t* raw_bytes,
const unsigned int raw_bytes_len,
const unsigned int MAX_OBJDUMP_BUFFER_LEN,
char* objdump_output_buffer);
// Parses the objdump output given in |objdump_output_buffer| and extracts
// the line of the first instruction into |instruction_line|. Returns true
// when the instruction line is successfully extracted.
static bool GetObjdumpInstructionLine(
const char* objdump_output_buffer,
string* instruction_line);
// Tokenizes out the operation and operands from a line of instruction
// disassembled by objdump. This method modifies the pointers to match the
// tokens of the instruction, and returns if the tokenizing was a success.
// The caller owns all pointers.
static bool TokenizeObjdumpInstruction(const string& line,
string* operation,
string* dest,
string* src);
// Calculates the effective address of an expression in the form reg+a or
// reg-a, where 'reg' is a register and 'a' is a constant, and writes the
// result in the pointer. The method returns whether the calculation was
// a success. The caller owns the pointer.
static bool CalculateAddress(const string& address_expression,
const DumpContext& context,
uint64_t* write_address);
#endif // _WIN32
// Checks if the stack pointer points to a memory mapping that is not
// labelled as the stack.
bool StackPointerOffStack(uint64_t stack_ptr);
// Checks if the stack or heap are marked executable according
// to the memory mappings.
bool ExecutableStackOrHeap();
// Whether this exploitability engine is permitted to shell out to objdump
// to disassemble raw bytes.
bool enable_objdump_;
};
} // namespace google_breakpad
#endif // GOOGLE_BREAKPAD_PROCESSOR_EXPLOITABILITY_LINUX_H_
|