Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3)

Side by Side Diff: snapshot/win/pe_image_reader.cc

Issue 1475023004: Get module versions and types from in-memory images (Closed) Base URL: https://chromium.googlesource.com/crashpad/crashpad@master
Patch Set: Address review feedback (2) Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « snapshot/win/pe_image_reader.h ('k') | snapshot/win/pe_image_reader_test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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"
22 #include "client/crashpad_info.h" 21 #include "client/crashpad_info.h"
23 #include "snapshot/win/process_reader_win.h" 22 #include "snapshot/win/pe_image_resource_reader.h"
24 #include "util/misc/pdb_structures.h" 23 #include "util/misc/pdb_structures.h"
25 #include "util/win/process_structs.h" 24 #include "util/win/process_structs.h"
26 25
27 namespace crashpad { 26 namespace crashpad {
28 27
29 namespace { 28 namespace {
30 29
31 std::string RangeToString(const CheckedWinAddressRange& range) {
32 return base::StringPrintf("[0x%llx + 0x%llx (%s)]",
33 range.Base(),
34 range.Size(),
35 range.Is64Bit() ? "64" : "32");
36 }
37
38 // Map from Traits to an IMAGE_NT_HEADERSxx. 30 // Map from Traits to an IMAGE_NT_HEADERSxx.
39 template <class Traits> 31 template <class Traits>
40 struct NtHeadersForTraits; 32 struct NtHeadersForTraits;
41 33
42 template <> 34 template <>
43 struct NtHeadersForTraits<process_types::internal::Traits32> { 35 struct NtHeadersForTraits<process_types::internal::Traits32> {
44 using type = IMAGE_NT_HEADERS32; 36 using type = IMAGE_NT_HEADERS32;
45 }; 37 };
46 38
47 template <> 39 template <>
48 struct NtHeadersForTraits<process_types::internal::Traits64> { 40 struct NtHeadersForTraits<process_types::internal::Traits64> {
49 using type = IMAGE_NT_HEADERS64; 41 using type = IMAGE_NT_HEADERS64;
50 }; 42 };
51 43
52 } // namespace 44 } // namespace
53 45
54 PEImageReader::PEImageReader() 46 PEImageReader::PEImageReader()
55 : process_reader_(nullptr), 47 : module_subrange_reader_(),
56 module_range_(),
57 module_name_(),
58 initialized_() { 48 initialized_() {
59 } 49 }
60 50
61 PEImageReader::~PEImageReader() { 51 PEImageReader::~PEImageReader() {
62 } 52 }
63 53
64 bool PEImageReader::Initialize(ProcessReaderWin* process_reader, 54 bool PEImageReader::Initialize(ProcessReaderWin* process_reader,
65 WinVMAddress address, 55 WinVMAddress address,
66 WinVMSize size, 56 WinVMSize size,
67 const std::string& module_name) { 57 const std::string& module_name) {
68 INITIALIZATION_STATE_SET_INITIALIZING(initialized_); 58 INITIALIZATION_STATE_SET_INITIALIZING(initialized_);
69 59
70 process_reader_ = process_reader; 60 if (!module_subrange_reader_.Initialize(
71 module_range_.SetRange(process_reader_->Is64Bit(), address, size); 61 process_reader, address, size, module_name)) {
72 if (!module_range_.IsValid()) {
73 LOG(WARNING) << "invalid module range for " << module_name << ": "
74 << RangeToString(module_range_);
75 return false; 62 return false;
76 } 63 }
77 module_name_ = module_name;
78 64
79 INITIALIZATION_STATE_SET_VALID(initialized_); 65 INITIALIZATION_STATE_SET_VALID(initialized_);
80 return true; 66 return true;
81 } 67 }
82 68
83 template <class Traits> 69 template <class Traits>
84 bool PEImageReader::GetCrashpadInfo( 70 bool PEImageReader::GetCrashpadInfo(
85 process_types::CrashpadInfo<Traits>* crashpad_info) const { 71 process_types::CrashpadInfo<Traits>* crashpad_info) const {
86 INITIALIZATION_STATE_DCHECK_VALID(initialized_); 72 INITIALIZATION_STATE_DCHECK_VALID(initialized_);
87 73
88 IMAGE_SECTION_HEADER section; 74 IMAGE_SECTION_HEADER section;
89 if (!GetSectionByName<typename NtHeadersForTraits<Traits>::type>("CPADinfo", 75 if (!GetSectionByName<typename NtHeadersForTraits<Traits>::type>("CPADinfo",
90 &section)) { 76 &section)) {
91 return false; 77 return false;
92 } 78 }
93 79
94 if (section.Misc.VirtualSize < sizeof(process_types::CrashpadInfo<Traits>)) { 80 if (section.Misc.VirtualSize < sizeof(process_types::CrashpadInfo<Traits>)) {
95 LOG(WARNING) << "small crashpad info section size " 81 LOG(WARNING) << "small crashpad info section size "
96 << section.Misc.VirtualSize << ", " << module_name_; 82 << section.Misc.VirtualSize << ", "
83 << module_subrange_reader_.name();
97 return false; 84 return false;
98 } 85 }
99 86
100 WinVMAddress crashpad_info_address = Address() + section.VirtualAddress; 87 ProcessSubrangeReader crashpad_info_subrange_reader;
101 CheckedWinAddressRange crashpad_info_range(process_reader_->Is64Bit(), 88 const WinVMAddress crashpad_info_address = Address() + section.VirtualAddress;
102 crashpad_info_address, 89 if (!crashpad_info_subrange_reader.InitializeSubrange(
103 section.Misc.VirtualSize); 90 module_subrange_reader_,
104 if (!crashpad_info_range.IsValid()) { 91 crashpad_info_address,
105 LOG(WARNING) << "invalid range for crashpad info: " 92 section.Misc.VirtualSize,
106 << RangeToString(crashpad_info_range); 93 "crashpad_info")) {
107 return false; 94 return false;
108 } 95 }
109 96
110 if (!module_range_.ContainsRange(crashpad_info_range)) { 97 if (!crashpad_info_subrange_reader.ReadMemory(
111 LOG(WARNING) << "crashpad info does not fall inside module " 98 crashpad_info_address,
112 << module_name_; 99 sizeof(process_types::CrashpadInfo<Traits>),
113 return false; 100 crashpad_info)) {
114 } 101 LOG(WARNING) << "could not read crashpad info from "
115 102 << module_subrange_reader_.name();
116 if (!process_reader_->ReadMemory(crashpad_info_address,
117 sizeof(process_types::CrashpadInfo<Traits>),
118 crashpad_info)) {
119 LOG(WARNING) << "could not read crashpad info " << module_name_;
120 return false; 103 return false;
121 } 104 }
122 105
123 if (crashpad_info->signature != CrashpadInfo::kSignature || 106 if (crashpad_info->signature != CrashpadInfo::kSignature ||
124 crashpad_info->version < 1) { 107 crashpad_info->version < 1) {
125 LOG(WARNING) << "unexpected crashpad info data " << module_name_; 108 LOG(WARNING) << "unexpected crashpad info data in "
109 << module_subrange_reader_.name();
126 return false; 110 return false;
127 } 111 }
128 112
129 return true; 113 return true;
130 } 114 }
131 115
132 bool PEImageReader::DebugDirectoryInformation(UUID* uuid, 116 bool PEImageReader::DebugDirectoryInformation(UUID* uuid,
133 DWORD* age, 117 DWORD* age,
134 std::string* pdbname) const { 118 std::string* pdbname) const {
135 if (process_reader_->Is64Bit()) { 119 INITIALIZATION_STATE_DCHECK_VALID(initialized_);
136 return ReadDebugDirectoryInformation<IMAGE_NT_HEADERS64>(
137 uuid, age, pdbname);
138 } else {
139 return ReadDebugDirectoryInformation<IMAGE_NT_HEADERS32>(
140 uuid, age, pdbname);
141 }
142 }
143 120
144 template <class NtHeadersType> 121 IMAGE_DATA_DIRECTORY data_directory;
145 bool PEImageReader::ReadDebugDirectoryInformation(UUID* uuid, 122 if (!ImageDataDirectoryEntry(IMAGE_DIRECTORY_ENTRY_DEBUG, &data_directory))
146 DWORD* age,
147 std::string* pdbname) const {
148 NtHeadersType nt_headers;
149 if (!ReadNtHeaders(&nt_headers, nullptr))
150 return false; 123 return false;
151 124
152 if (nt_headers.FileHeader.SizeOfOptionalHeader <
153 offsetof(decltype(nt_headers.OptionalHeader),
154 DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG]) +
155 sizeof(nt_headers.OptionalHeader
156 .DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG]) ||
157 nt_headers.OptionalHeader.NumberOfRvaAndSizes <=
158 IMAGE_DIRECTORY_ENTRY_DEBUG) {
159 return false;
160 }
161
162 const IMAGE_DATA_DIRECTORY& data_directory =
163 nt_headers.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG];
164 if (data_directory.VirtualAddress == 0 || data_directory.Size == 0)
165 return false;
166 IMAGE_DEBUG_DIRECTORY debug_directory; 125 IMAGE_DEBUG_DIRECTORY debug_directory;
167 if (data_directory.Size % sizeof(debug_directory) != 0) 126 if (data_directory.Size % sizeof(debug_directory) != 0)
168 return false; 127 return false;
169 for (size_t offset = 0; offset < data_directory.Size; 128 for (size_t offset = 0; offset < data_directory.Size;
170 offset += sizeof(debug_directory)) { 129 offset += sizeof(debug_directory)) {
171 if (!CheckedReadMemory(Address() + data_directory.VirtualAddress + offset, 130 if (!module_subrange_reader_.ReadMemory(
172 sizeof(debug_directory), 131 Address() + data_directory.VirtualAddress + offset,
173 &debug_directory)) { 132 sizeof(debug_directory),
174 LOG(WARNING) << "could not read data directory"; 133 &debug_directory)) {
134 LOG(WARNING) << "could not read data directory from "
135 << module_subrange_reader_.name();
175 return false; 136 return false;
176 } 137 }
177 138
178 if (debug_directory.Type != IMAGE_DEBUG_TYPE_CODEVIEW) 139 if (debug_directory.Type != IMAGE_DEBUG_TYPE_CODEVIEW)
179 continue; 140 continue;
180 141
181 if (debug_directory.AddressOfRawData) { 142 if (debug_directory.AddressOfRawData) {
182 if (debug_directory.SizeOfData < sizeof(CodeViewRecordPDB70)) { 143 if (debug_directory.SizeOfData < sizeof(CodeViewRecordPDB70)) {
183 LOG(WARNING) << "CodeView debug entry of unexpected size"; 144 LOG(WARNING) << "CodeView debug entry of unexpected size in "
145 << module_subrange_reader_.name();
184 continue; 146 continue;
185 } 147 }
186 148
187 scoped_ptr<char[]> data(new char[debug_directory.SizeOfData]); 149 scoped_ptr<char[]> data(new char[debug_directory.SizeOfData]);
188 if (!CheckedReadMemory(Address() + debug_directory.AddressOfRawData, 150 if (!module_subrange_reader_.ReadMemory(
189 debug_directory.SizeOfData, 151 Address() + debug_directory.AddressOfRawData,
190 data.get())) { 152 debug_directory.SizeOfData,
191 LOG(WARNING) << "could not read debug directory"; 153 data.get())) {
154 LOG(WARNING) << "could not read debug directory from "
155 << module_subrange_reader_.name();
192 return false; 156 return false;
193 } 157 }
194 158
195 if (*reinterpret_cast<DWORD*>(data.get()) != 159 if (*reinterpret_cast<DWORD*>(data.get()) !=
196 CodeViewRecordPDB70::kSignature) { 160 CodeViewRecordPDB70::kSignature) {
197 LOG(WARNING) << "encountered non-7.0 CodeView debug record"; 161 LOG(WARNING) << "encountered non-7.0 CodeView debug record in "
162 << module_subrange_reader_.name();
198 continue; 163 continue;
199 } 164 }
200 165
201 CodeViewRecordPDB70* codeview = 166 CodeViewRecordPDB70* codeview =
202 reinterpret_cast<CodeViewRecordPDB70*>(data.get()); 167 reinterpret_cast<CodeViewRecordPDB70*>(data.get());
203 *uuid = codeview->uuid; 168 *uuid = codeview->uuid;
204 *age = codeview->age; 169 *age = codeview->age;
205 // This is a NUL-terminated string encoded in the codepage of the system 170 // This is a NUL-terminated string encoded in the codepage of the system
206 // where the binary was linked. We have no idea what that was, so we just 171 // where the binary was linked. We have no idea what that was, so we just
207 // assume ASCII. 172 // assume ASCII.
208 *pdbname = std::string(reinterpret_cast<char*>(&codeview->pdb_name[0])); 173 *pdbname = std::string(reinterpret_cast<char*>(&codeview->pdb_name[0]));
209 return true; 174 return true;
210 } else if (debug_directory.PointerToRawData) { 175 } else if (debug_directory.PointerToRawData) {
211 // This occurs for non-PDB based debug information. We simply ignore these 176 // This occurs for non-PDB based debug information. We simply ignore these
212 // as we don't expect to encounter modules that will be in this format 177 // as we don't expect to encounter modules that will be in this format
213 // for which we'll actually have symbols. See 178 // for which we'll actually have symbols. See
214 // https://crashpad.chromium.org/bug/47. 179 // https://crashpad.chromium.org/bug/47.
215 } 180 }
216 } 181 }
217 182
218 return false; 183 return false;
219 } 184 }
220 185
186 bool PEImageReader::VSFixedFileInfo(
187 VS_FIXEDFILEINFO* vs_fixed_file_info) const {
188 INITIALIZATION_STATE_DCHECK_VALID(initialized_);
189
190 IMAGE_DATA_DIRECTORY data_directory;
191 if (!ImageDataDirectoryEntry(IMAGE_DIRECTORY_ENTRY_RESOURCE,
192 &data_directory)) {
193 return false;
194 }
195
196 PEImageResourceReader resource_reader;
197 if (!resource_reader.Initialize(module_subrange_reader_, data_directory)) {
198 return false;
199 }
200
201 WinVMAddress address;
202 WinVMSize size;
203 if (!resource_reader.FindResourceByID(
204 reinterpret_cast<uint16_t>(VS_FILE_INFO), // RT_VERSION
205 VS_VERSION_INFO,
206 MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL),
207 &address,
208 &size,
209 nullptr)) {
210 return false;
211 }
212
213 // This structure is not declared anywhere in the SDK, but is documented at
214 // https://msdn.microsoft.com/en-us/library/windows/desktop/ms647001.aspx.
215 struct VS_VERSIONINFO {
216 WORD wLength;
217 WORD wValueLength;
218 WORD wType;
219
220 // The structure documentation on MSDN doesn’t show the [16], but it does
221 // say that it’s supposed to be L"VS_VERSION_INFO", which is is in fact a
222 // 16-character string (including its NUL terminator).
223 WCHAR szKey[16];
224
225 WORD Padding1;
226 VS_FIXEDFILEINFO Value;
227
228 // Don’t include Children or the Padding2 that precedes it, because they may
229 // not be present.
230 // WORD Padding2;
231 // WORD Children;
232 };
233 VS_VERSIONINFO version_info;
234
235 if (size < sizeof(version_info)) {
236 LOG(WARNING) << "version info size " << size
237 << " too small for structure of size " << sizeof(version_info)
238 << " in " << module_subrange_reader_.name();
239 return false;
240 }
241
242 if (!module_subrange_reader_.ReadMemory(
243 address, sizeof(version_info), &version_info)) {
244 LOG(WARNING) << "could not read version info from "
245 << module_subrange_reader_.name();
246 return false;
247 }
248
249 if (version_info.wLength < sizeof(version_info) ||
250 version_info.wValueLength != sizeof(version_info.Value) ||
251 version_info.wType != 0 ||
252 wcsncmp(version_info.szKey,
253 L"VS_VERSION_INFO",
254 arraysize(version_info.szKey)) != 0) {
255 LOG(WARNING) << "unexpected VS_VERSIONINFO in "
256 << module_subrange_reader_.name();
257 return false;
258 }
259
260 if (version_info.Value.dwSignature != VS_FFI_SIGNATURE ||
261 version_info.Value.dwStrucVersion != VS_FFI_STRUCVERSION) {
262 LOG(WARNING) << "unexpected VS_FIXEDFILEINFO in "
263 << module_subrange_reader_.name();
264 return false;
265 }
266
267 *vs_fixed_file_info = version_info.Value;
268 vs_fixed_file_info->dwFileFlags &= vs_fixed_file_info->dwFileFlagsMask;
269 return true;
270 }
271
221 template <class NtHeadersType> 272 template <class NtHeadersType>
222 bool PEImageReader::ReadNtHeaders(NtHeadersType* nt_headers, 273 bool PEImageReader::ReadNtHeaders(NtHeadersType* nt_headers,
223 WinVMAddress* nt_headers_address) const { 274 WinVMAddress* nt_headers_address) const {
224 IMAGE_DOS_HEADER dos_header; 275 IMAGE_DOS_HEADER dos_header;
225 if (!CheckedReadMemory(Address(), sizeof(IMAGE_DOS_HEADER), &dos_header)) { 276 if (!module_subrange_reader_.ReadMemory(
226 LOG(WARNING) << "could not read dos header of " << module_name_; 277 Address(), sizeof(IMAGE_DOS_HEADER), &dos_header)) {
278 LOG(WARNING) << "could not read dos header from "
279 << module_subrange_reader_.name();
227 return false; 280 return false;
228 } 281 }
229 282
230 if (dos_header.e_magic != IMAGE_DOS_SIGNATURE) { 283 if (dos_header.e_magic != IMAGE_DOS_SIGNATURE) {
231 LOG(WARNING) << "invalid e_magic in dos header of " << module_name_; 284 LOG(WARNING) << "invalid e_magic in dos header of "
285 << module_subrange_reader_.name();
232 return false; 286 return false;
233 } 287 }
234 288
235 WinVMAddress local_nt_headers_address = Address() + dos_header.e_lfanew; 289 WinVMAddress local_nt_headers_address = Address() + dos_header.e_lfanew;
236 if (!CheckedReadMemory( 290 if (!module_subrange_reader_.ReadMemory(
237 local_nt_headers_address, sizeof(NtHeadersType), nt_headers)) { 291 local_nt_headers_address, sizeof(NtHeadersType), nt_headers)) {
238 LOG(WARNING) << "could not read nt headers of " << module_name_; 292 LOG(WARNING) << "could not read nt headers from "
293 << module_subrange_reader_.name();
239 return false; 294 return false;
240 } 295 }
241 296
242 if (nt_headers->Signature != IMAGE_NT_SIGNATURE) { 297 if (nt_headers->Signature != IMAGE_NT_SIGNATURE) {
243 LOG(WARNING) << "invalid signature in nt headers of " << module_name_; 298 LOG(WARNING) << "invalid signature in nt headers of "
299 << module_subrange_reader_.name();
244 return false; 300 return false;
245 } 301 }
246 302
247 if (nt_headers_address) 303 if (nt_headers_address)
248 *nt_headers_address = local_nt_headers_address; 304 *nt_headers_address = local_nt_headers_address;
249 305
250 return true; 306 return true;
251 } 307 }
252 308
253 template <class NtHeadersType> 309 template <class NtHeadersType>
254 bool PEImageReader::GetSectionByName(const std::string& name, 310 bool PEImageReader::GetSectionByName(const std::string& name,
255 IMAGE_SECTION_HEADER* section) const { 311 IMAGE_SECTION_HEADER* section) const {
256 if (name.size() > sizeof(section->Name)) { 312 if (name.size() > sizeof(section->Name)) {
257 LOG(WARNING) << "supplied section name too long " << name; 313 LOG(WARNING) << "supplied section name too long " << name;
258 return false; 314 return false;
259 } 315 }
260 316
261 NtHeadersType nt_headers; 317 NtHeadersType nt_headers;
262 WinVMAddress nt_headers_address; 318 WinVMAddress nt_headers_address;
263 if (!ReadNtHeaders(&nt_headers, &nt_headers_address)) 319 if (!ReadNtHeaders(&nt_headers, &nt_headers_address))
264 return false; 320 return false;
265 321
266 WinVMAddress first_section_address = 322 WinVMAddress first_section_address =
267 nt_headers_address + offsetof(NtHeadersType, OptionalHeader) + 323 nt_headers_address + offsetof(NtHeadersType, OptionalHeader) +
268 nt_headers.FileHeader.SizeOfOptionalHeader; 324 nt_headers.FileHeader.SizeOfOptionalHeader;
269 for (DWORD i = 0; i < nt_headers.FileHeader.NumberOfSections; ++i) { 325 for (DWORD i = 0; i < nt_headers.FileHeader.NumberOfSections; ++i) {
270 WinVMAddress section_address = 326 WinVMAddress section_address =
271 first_section_address + sizeof(IMAGE_SECTION_HEADER) * i; 327 first_section_address + sizeof(IMAGE_SECTION_HEADER) * i;
272 if (!CheckedReadMemory( 328 if (!module_subrange_reader_.ReadMemory(
273 section_address, sizeof(IMAGE_SECTION_HEADER), section)) { 329 section_address, sizeof(IMAGE_SECTION_HEADER), section)) {
274 LOG(WARNING) << "could not read section " << i << " of " << module_name_; 330 LOG(WARNING) << "could not read section " << i << " from "
331 << module_subrange_reader_.name();
275 return false; 332 return false;
276 } 333 }
277 if (strncmp(reinterpret_cast<const char*>(section->Name), 334 if (strncmp(reinterpret_cast<const char*>(section->Name),
278 name.c_str(), 335 name.c_str(),
279 sizeof(section->Name)) == 0) { 336 sizeof(section->Name)) == 0) {
280 return true; 337 return true;
281 } 338 }
282 } 339 }
283 340
284 return false; 341 return false;
285 } 342 }
286 343
287 bool PEImageReader::CheckedReadMemory(WinVMAddress address, 344 bool PEImageReader::ImageDataDirectoryEntry(size_t index,
288 WinVMSize size, 345 IMAGE_DATA_DIRECTORY* entry) const {
289 void* into) const { 346 bool rv;
290 CheckedWinAddressRange read_range(process_reader_->Is64Bit(), address, size); 347 if (module_subrange_reader_.Is64Bit()) {
291 if (!read_range.IsValid()) { 348 rv = ImageDataDirectoryEntryT<IMAGE_NT_HEADERS64>(index, entry);
292 LOG(WARNING) << "invalid read range: " << RangeToString(read_range); 349 } else {
350 rv = ImageDataDirectoryEntryT<IMAGE_NT_HEADERS32>(index, entry);
351 }
352
353 return rv && entry->VirtualAddress != 0 && entry->Size != 0;
354 }
355
356 template <class NtHeadersType>
357 bool PEImageReader::ImageDataDirectoryEntryT(
358 size_t index,
359 IMAGE_DATA_DIRECTORY* entry) const {
360 NtHeadersType nt_headers;
361 if (!ReadNtHeaders(&nt_headers, nullptr)) {
293 return false; 362 return false;
294 } 363 }
295 if (!module_range_.ContainsRange(read_range)) { 364
296 LOG(WARNING) << "attempt to read outside of module " << module_name_ 365 if (nt_headers.FileHeader.SizeOfOptionalHeader <
297 << " at range: " << RangeToString(read_range); 366 offsetof(decltype(nt_headers.OptionalHeader), DataDirectory[index]) +
367 sizeof(nt_headers.OptionalHeader.DataDirectory[index]) ||
368 nt_headers.OptionalHeader.NumberOfRvaAndSizes <= index) {
298 return false; 369 return false;
299 } 370 }
300 return process_reader_->ReadMemory(address, size, into); 371
372 *entry = nt_headers.OptionalHeader.DataDirectory[index];
373 return true;
301 } 374 }
302 375
303 // Explicit instantiations with the only 2 valid template arguments to avoid 376 // Explicit instantiations with the only 2 valid template arguments to avoid
304 // putting the body of the function in the header. 377 // putting the body of the function in the header.
305 template bool PEImageReader::GetCrashpadInfo<process_types::internal::Traits32>( 378 template bool PEImageReader::GetCrashpadInfo<process_types::internal::Traits32>(
306 process_types::CrashpadInfo<process_types::internal::Traits32>* 379 process_types::CrashpadInfo<process_types::internal::Traits32>*
307 crashpad_info) const; 380 crashpad_info) const;
308 template bool PEImageReader::GetCrashpadInfo<process_types::internal::Traits64>( 381 template bool PEImageReader::GetCrashpadInfo<process_types::internal::Traits64>(
309 process_types::CrashpadInfo<process_types::internal::Traits64>* 382 process_types::CrashpadInfo<process_types::internal::Traits64>*
310 crashpad_info) const; 383 crashpad_info) const;
311 384
312 } // namespace crashpad 385 } // namespace crashpad
OLDNEW
« no previous file with comments | « snapshot/win/pe_image_reader.h ('k') | snapshot/win/pe_image_reader_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698