blob: 704c55b26a82931b70398c8df347f91dfc9642f7 (
plain)
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
|
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/app/crash_analysis_win.h"
#include "breakpad/src/client/windows/handler/exception_handler.h"
#include "chrome/app/breakpad_win.h"
namespace {
// We start reporting at 400MB of executable memory.
size_t kAbnormalExecMemCutoff = 0x19000;
// To avoid resizing the vector of memory regions while in a crashed state we
// limit the size.
size_t kMaxMappings = 2048;
}
extern "C" void DumpProcessAbnormalSignature();
CrashAnalysis::CrashAnalysis()
: exec_pages_(0) {
memory_regions_.reserve(kMaxMappings);
}
// Alayze a crash to determine whether reporting additional crash details is
// desirable. Specifcally we are interested in crashes which appear
// particularly exploitable or which appear to be failed attempts at
// exploitation.
void CrashAnalysis::Analyze(_EXCEPTION_POINTERS* info) {
// Get system page size.
SYSTEM_INFO system_info = {0};
GetSystemInfo(&system_info);
DWORD prev_protection = NULL;
MEMORY_BASIC_INFORMATION mbi = {0};
void* base_address = NULL;
// Build a vector of the current memory mappings for the process.
// This will allow us to easily sample memory looking for the various
// signatures and patterns which interest us.
while (VirtualQuery(base_address, &mbi, sizeof(mbi)) ==
sizeof(mbi)) {
if (mbi.State == MEM_COMMIT && memory_regions_.size() < kMaxMappings) {
memory_regions_.push_back(mbi);
if (mbi.Protect &
(PAGE_EXECUTE || PAGE_EXECUTE_READ || PAGE_EXECUTE_READWRITE)) {
exec_pages_ += mbi.RegionSize / system_info.dwPageSize;
if (mbi.Protect & PAGE_EXECUTE_READWRITE &&
!(prev_protection &
(PAGE_GUARD || PAGE_NOACCESS || PAGE_EXECUTE_READWRITE))) {
// There should never be a write/execute mapping without a guard page
// in front. Send the report and quit early.
DumpProcessAbnormalSignature();
return;
}
}
prev_protection = mbi.Protect;
}
void* new_base = (static_cast<BYTE*>(mbi.BaseAddress)) + mbi.RegionSize;
base_address = new_base;
}
// We trigger upload if the process has mapped more than the threashold of
// executable memory.
if (exec_pages_ > kAbnormalExecMemCutoff) {
DumpProcessAbnormalSignature();
return;
}
// TODO(cdn): Moar checks for abnormality.
return;
}
|