OLD | NEW |
1 // Copyright 2015 The Crashpad Authors. All rights reserved. | 1 // Copyright 2015 The Crashpad Authors. All rights reserved. |
2 // | 2 // |
3 // Licensed under the Apache License, Version 2.0 (the "License"); | 3 // Licensed under the Apache License, Version 2.0 (the "License"); |
4 // you may not use this file except in compliance with the License. | 4 // you may not use this file except in compliance with the License. |
5 // You may obtain a copy of the License at | 5 // You may obtain a copy of the License at |
6 // | 6 // |
7 // http://www.apache.org/licenses/LICENSE-2.0 | 7 // http://www.apache.org/licenses/LICENSE-2.0 |
8 // | 8 // |
9 // Unless required by applicable law or agreed to in writing, software | 9 // Unless required by applicable law or agreed to in writing, software |
10 // distributed under the License is distributed on an "AS IS" BASIS, | 10 // distributed under the License is distributed on an "AS IS" BASIS, |
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
12 // See the License for the specific language governing permissions and | 12 // See the License for the specific language governing permissions and |
13 // limitations under the License. | 13 // limitations under the License. |
14 | 14 |
15 #include "snapshot/win/pe_image_reader.h" | 15 #include "snapshot/win/pe_image_reader.h" |
16 | 16 |
17 #include <string.h> | 17 #include <string.h> |
18 | 18 |
19 #include "base/logging.h" | 19 #include "base/logging.h" |
20 #include "base/memory/scoped_ptr.h" | 20 #include "base/memory/scoped_ptr.h" |
21 #include "base/strings/stringprintf.h" | 21 #include "base/strings/stringprintf.h" |
22 #include "client/crashpad_info.h" | 22 #include "client/crashpad_info.h" |
23 #include "snapshot/win/process_reader_win.h" | 23 #include "snapshot/win/process_reader_win.h" |
24 #include "util/misc/pdb_structures.h" | 24 #include "util/misc/pdb_structures.h" |
| 25 #include "util/win/process_structs.h" |
25 | 26 |
26 namespace crashpad { | 27 namespace crashpad { |
27 | 28 |
28 namespace { | 29 namespace { |
29 | 30 |
30 std::string RangeToString(const CheckedWinAddressRange& range) { | 31 std::string RangeToString(const CheckedWinAddressRange& range) { |
31 return base::StringPrintf("[0x%llx + 0x%llx (%s)]", | 32 return base::StringPrintf("[0x%llx + 0x%llx (%s)]", |
32 range.Base(), | 33 range.Base(), |
33 range.Size(), | 34 range.Size(), |
34 range.Is64Bit() ? "64" : "32"); | 35 range.Is64Bit() ? "64" : "32"); |
35 } | 36 } |
36 | 37 |
| 38 // Map from Traits to an IMAGE_NT_HEADERSxx. |
| 39 template <class Traits> |
| 40 struct NtHeadersForTraits; |
| 41 |
| 42 template <> |
| 43 struct NtHeadersForTraits<process_types::internal::Traits32> { |
| 44 using type = IMAGE_NT_HEADERS32; |
| 45 }; |
| 46 |
| 47 template <> |
| 48 struct NtHeadersForTraits<process_types::internal::Traits64> { |
| 49 using type = IMAGE_NT_HEADERS64; |
| 50 }; |
| 51 |
37 } // namespace | 52 } // namespace |
38 | 53 |
39 PEImageReader::PEImageReader() | 54 PEImageReader::PEImageReader() |
40 : process_reader_(nullptr), | 55 : process_reader_(nullptr), |
41 module_range_(), | 56 module_range_(), |
42 module_name_(), | 57 module_name_(), |
43 initialized_() { | 58 initialized_() { |
44 } | 59 } |
45 | 60 |
46 PEImageReader::~PEImageReader() { | 61 PEImageReader::~PEImageReader() { |
(...skipping 11 matching lines...) Expand all Loading... |
58 LOG(WARNING) << "invalid module range for " << module_name << ": " | 73 LOG(WARNING) << "invalid module range for " << module_name << ": " |
59 << RangeToString(module_range_); | 74 << RangeToString(module_range_); |
60 return false; | 75 return false; |
61 } | 76 } |
62 module_name_ = module_name; | 77 module_name_ = module_name; |
63 | 78 |
64 INITIALIZATION_STATE_SET_VALID(initialized_); | 79 INITIALIZATION_STATE_SET_VALID(initialized_); |
65 return true; | 80 return true; |
66 } | 81 } |
67 | 82 |
| 83 template <class Traits> |
68 bool PEImageReader::GetCrashpadInfo( | 84 bool PEImageReader::GetCrashpadInfo( |
69 process_types::CrashpadInfo* crashpad_info) const { | 85 process_types::CrashpadInfo<Traits>* crashpad_info) const { |
70 INITIALIZATION_STATE_DCHECK_VALID(initialized_); | 86 INITIALIZATION_STATE_DCHECK_VALID(initialized_); |
71 | 87 |
72 IMAGE_SECTION_HEADER section; | 88 IMAGE_SECTION_HEADER section; |
73 if (process_reader_->Is64Bit()) { | 89 if (!GetSectionByName<NtHeadersForTraits<Traits>::type>("CPADinfo", §ion)) |
74 if (!GetSectionByName<IMAGE_NT_HEADERS64>("CPADinfo", §ion)) | 90 return false; |
75 return false; | |
76 } else { | |
77 if (!GetSectionByName<IMAGE_NT_HEADERS32>("CPADinfo", §ion)) | |
78 return false; | |
79 } | |
80 | 91 |
81 if (section.Misc.VirtualSize < sizeof(process_types::CrashpadInfo)) { | 92 if (section.Misc.VirtualSize < sizeof(process_types::CrashpadInfo<Traits>)) { |
82 LOG(WARNING) << "small crashpad info section size " | 93 LOG(WARNING) << "small crashpad info section size " |
83 << section.Misc.VirtualSize << ", " << module_name_; | 94 << section.Misc.VirtualSize << ", " << module_name_; |
84 return false; | 95 return false; |
85 } | 96 } |
86 | 97 |
87 WinVMAddress crashpad_info_address = Address() + section.VirtualAddress; | 98 WinVMAddress crashpad_info_address = Address() + section.VirtualAddress; |
88 CheckedWinAddressRange crashpad_info_range(process_reader_->Is64Bit(), | 99 CheckedWinAddressRange crashpad_info_range(process_reader_->Is64Bit(), |
89 crashpad_info_address, | 100 crashpad_info_address, |
90 section.Misc.VirtualSize); | 101 section.Misc.VirtualSize); |
91 if (!crashpad_info_range.IsValid()) { | 102 if (!crashpad_info_range.IsValid()) { |
92 LOG(WARNING) << "invalid range for crashpad info: " | 103 LOG(WARNING) << "invalid range for crashpad info: " |
93 << RangeToString(crashpad_info_range); | 104 << RangeToString(crashpad_info_range); |
94 return false; | 105 return false; |
95 } | 106 } |
96 | 107 |
97 if (!module_range_.ContainsRange(crashpad_info_range)) { | 108 if (!module_range_.ContainsRange(crashpad_info_range)) { |
98 LOG(WARNING) << "crashpad info does not fall inside module " | 109 LOG(WARNING) << "crashpad info does not fall inside module " |
99 << module_name_; | 110 << module_name_; |
100 return false; | 111 return false; |
101 } | 112 } |
102 | 113 |
103 // TODO(scottmg): process_types for cross-bitness. | |
104 if (!process_reader_->ReadMemory(crashpad_info_address, | 114 if (!process_reader_->ReadMemory(crashpad_info_address, |
105 sizeof(process_types::CrashpadInfo), | 115 sizeof(process_types::CrashpadInfo<Traits>), |
106 crashpad_info)) { | 116 crashpad_info)) { |
107 LOG(WARNING) << "could not read crashpad info " << module_name_; | 117 LOG(WARNING) << "could not read crashpad info " << module_name_; |
108 return false; | 118 return false; |
109 } | 119 } |
110 | 120 |
111 if (crashpad_info->signature != CrashpadInfo::kSignature || | 121 if (crashpad_info->signature != CrashpadInfo::kSignature || |
112 crashpad_info->version < 1) { | 122 crashpad_info->version < 1) { |
113 LOG(WARNING) << "unexpected crashpad info data " << module_name_; | 123 LOG(WARNING) << "unexpected crashpad info data " << module_name_; |
114 return false; | 124 return false; |
115 } | 125 } |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
263 return false; | 273 return false; |
264 } | 274 } |
265 if (!module_range_.ContainsRange(read_range)) { | 275 if (!module_range_.ContainsRange(read_range)) { |
266 LOG(WARNING) << "attempt to read outside of module " << module_name_ | 276 LOG(WARNING) << "attempt to read outside of module " << module_name_ |
267 << " at range: " << RangeToString(read_range); | 277 << " at range: " << RangeToString(read_range); |
268 return false; | 278 return false; |
269 } | 279 } |
270 return process_reader_->ReadMemory(address, size, into); | 280 return process_reader_->ReadMemory(address, size, into); |
271 } | 281 } |
272 | 282 |
| 283 // Explicit instantiations with the only 2 valid template arguments to avoid |
| 284 // putting the body of the function in the header. |
| 285 template bool PEImageReader::GetCrashpadInfo<process_types::internal::Traits32>( |
| 286 process_types::CrashpadInfo<process_types::internal::Traits32>* |
| 287 crashpad_info) const; |
| 288 template bool PEImageReader::GetCrashpadInfo<process_types::internal::Traits64>( |
| 289 process_types::CrashpadInfo<process_types::internal::Traits64>* |
| 290 crashpad_info) const; |
| 291 |
273 } // namespace crashpad | 292 } // namespace crashpad |
OLD | NEW |