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, |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
100 PLOG(ERROR) << "ReadProcessMemory " << __FUNCSIG__; | 100 PLOG(ERROR) << "ReadProcessMemory " << __FUNCSIG__; |
101 return false; | 101 return false; |
102 } | 102 } |
103 if (bytes_read != sizeof(T)) { | 103 if (bytes_read != sizeof(T)) { |
104 LOG(ERROR) << "ReadProcessMemory " << __FUNCSIG__ << " incorrect size"; | 104 LOG(ERROR) << "ReadProcessMemory " << __FUNCSIG__ << " incorrect size"; |
105 return false; | 105 return false; |
106 } | 106 } |
107 return true; | 107 return true; |
108 } | 108 } |
109 | 109 |
110 bool RegionIsAccessible(const ProcessInfo::MemoryInfo& memory_info) { | 110 bool RegionIsAccessible(const MEMORY_BASIC_INFORMATION64& memory_info) { |
111 return memory_info.state == MEM_COMMIT && | 111 return memory_info.State == MEM_COMMIT && |
112 (memory_info.protect & PAGE_NOACCESS) == 0 && | 112 (memory_info.Protect & PAGE_NOACCESS) == 0 && |
113 (memory_info.protect & PAGE_GUARD) == 0; | 113 (memory_info.Protect & PAGE_GUARD) == 0; |
114 } | |
115 | |
116 MEMORY_BASIC_INFORMATION64 MemoryBasicInformationToMemoryBasicInformation64( | |
117 const MEMORY_BASIC_INFORMATION& mbi) { | |
118 MEMORY_BASIC_INFORMATION64 mbi64 = {0}; | |
119 mbi64.BaseAddress = reinterpret_cast<ULONGLONG>(mbi.BaseAddress); | |
120 mbi64.AllocationBase = reinterpret_cast<ULONGLONG>(mbi.AllocationBase); | |
121 mbi64.AllocationProtect = mbi.AllocationProtect; | |
122 mbi64.RegionSize = mbi.RegionSize; | |
123 mbi64.State = mbi.State; | |
124 mbi64.Protect = mbi.Protect; | |
125 mbi64.Type = mbi.Type; | |
126 return mbi64; | |
114 } | 127 } |
115 | 128 |
116 } // namespace | 129 } // namespace |
117 | 130 |
118 template <class Traits> | 131 template <class Traits> |
119 bool GetProcessBasicInformation(HANDLE process, | 132 bool GetProcessBasicInformation(HANDLE process, |
120 bool is_wow64, | 133 bool is_wow64, |
121 ProcessInfo* process_info, | 134 ProcessInfo* process_info, |
122 WinVMAddress* peb_address, | 135 WinVMAddress* peb_address, |
123 WinVMSize* peb_size) { | 136 WinVMSize* peb_size) { |
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
281 &memory_basic_information, | 294 &memory_basic_information, |
282 sizeof(memory_basic_information)); | 295 sizeof(memory_basic_information)); |
283 if (result == 0) { | 296 if (result == 0) { |
284 if (GetLastError() == ERROR_INVALID_PARAMETER) | 297 if (GetLastError() == ERROR_INVALID_PARAMETER) |
285 break; | 298 break; |
286 PLOG(ERROR) << "VirtualQueryEx"; | 299 PLOG(ERROR) << "VirtualQueryEx"; |
287 return false; | 300 return false; |
288 } | 301 } |
289 | 302 |
290 process_info->memory_info_.push_back( | 303 process_info->memory_info_.push_back( |
291 ProcessInfo::MemoryInfo(memory_basic_information)); | 304 MemoryBasicInformationToMemoryBasicInformation64( |
305 memory_basic_information)); | |
292 | 306 |
293 if (memory_basic_information.RegionSize == 0) { | 307 if (memory_basic_information.RegionSize == 0) { |
294 LOG(ERROR) << "RegionSize == 0"; | 308 LOG(ERROR) << "RegionSize == 0"; |
295 return false; | 309 return false; |
296 } | 310 } |
297 } | 311 } |
298 | 312 |
299 return true; | 313 return true; |
300 } | 314 } |
301 | 315 |
302 ProcessInfo::Module::Module() : name(), dll_base(0), size(0), timestamp() { | 316 ProcessInfo::Module::Module() : name(), dll_base(0), size(0), timestamp() { |
303 } | 317 } |
304 | 318 |
305 ProcessInfo::Module::~Module() { | 319 ProcessInfo::Module::~Module() { |
306 } | 320 } |
307 | 321 |
308 ProcessInfo::MemoryInfo::MemoryInfo(const MEMORY_BASIC_INFORMATION& mbi) | |
309 : base_address(reinterpret_cast<WinVMAddress>(mbi.BaseAddress)), | |
310 region_size(mbi.RegionSize), | |
311 allocation_base(reinterpret_cast<WinVMAddress>(mbi.AllocationBase)), | |
312 state(mbi.State), | |
313 allocation_protect(mbi.AllocationProtect), | |
314 protect(mbi.Protect), | |
315 type(mbi.Type) { | |
316 } | |
317 | |
318 ProcessInfo::MemoryInfo::~MemoryInfo() { | |
319 } | |
320 | |
321 ProcessInfo::ProcessInfo() | 322 ProcessInfo::ProcessInfo() |
322 : process_id_(), | 323 : process_id_(), |
323 inherited_from_process_id_(), | 324 inherited_from_process_id_(), |
324 command_line_(), | 325 command_line_(), |
325 peb_address_(0), | 326 peb_address_(0), |
326 peb_size_(0), | 327 peb_size_(0), |
327 modules_(), | 328 modules_(), |
328 memory_info_(), | 329 memory_info_(), |
329 is_64_bit_(false), | 330 is_64_bit_(false), |
330 is_wow64_(false), | 331 is_wow64_(false), |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
419 *peb_address = peb_address_; | 420 *peb_address = peb_address_; |
420 *peb_size = peb_size_; | 421 *peb_size = peb_size_; |
421 } | 422 } |
422 | 423 |
423 bool ProcessInfo::Modules(std::vector<Module>* modules) const { | 424 bool ProcessInfo::Modules(std::vector<Module>* modules) const { |
424 INITIALIZATION_STATE_DCHECK_VALID(initialized_); | 425 INITIALIZATION_STATE_DCHECK_VALID(initialized_); |
425 *modules = modules_; | 426 *modules = modules_; |
426 return true; | 427 return true; |
427 } | 428 } |
428 | 429 |
429 const std::vector<ProcessInfo::MemoryInfo>& ProcessInfo::MemoryInformation() | 430 const std::vector<MEMORY_BASIC_INFORMATION64>& ProcessInfo::MemoryInfo() const { |
430 const { | |
431 INITIALIZATION_STATE_DCHECK_VALID(initialized_); | 431 INITIALIZATION_STATE_DCHECK_VALID(initialized_); |
432 return memory_info_; | 432 return memory_info_; |
433 } | 433 } |
434 | 434 |
435 std::vector<CheckedRange<WinVMAddress, WinVMSize>> | 435 std::vector<CheckedRange<WinVMAddress, WinVMSize>> |
436 ProcessInfo::GetReadableRanges( | 436 ProcessInfo::GetReadableRanges( |
437 const CheckedRange<WinVMAddress, WinVMSize>& range) const { | 437 const CheckedRange<WinVMAddress, WinVMSize>& range) const { |
438 return GetReadableRangesOfMemoryMap(range, MemoryInformation()); | 438 return GetReadableRangesOfMemoryMap(range, MemoryInfo()); |
439 } | 439 } |
440 | 440 |
441 std::vector<CheckedRange<WinVMAddress, WinVMSize>> GetReadableRangesOfMemoryMap( | 441 std::vector<CheckedRange<WinVMAddress, WinVMSize>> GetReadableRangesOfMemoryMap( |
442 const CheckedRange<WinVMAddress, WinVMSize>& range, | 442 const CheckedRange<WinVMAddress, WinVMSize>& range, |
443 const std::vector<ProcessInfo::MemoryInfo>& memory_info) { | 443 const std::vector<MEMORY_BASIC_INFORMATION64>& memory_info) { |
444 using Range = CheckedRange<WinVMAddress, WinVMSize>; | 444 using Range = CheckedRange<WinVMAddress, WinVMSize>; |
445 | 445 |
446 // Find all the ranges that overlap the target range, maintaining their order. | 446 // Find all the ranges that overlap the target range, maintaining their order. |
447 std::vector<ProcessInfo::MemoryInfo> overlapping; | 447 std::vector<MEMORY_BASIC_INFORMATION64> overlapping; |
448 for (const auto& mi : memory_info) { | 448 for (const auto& mi : memory_info) { |
449 if (range.OverlapsRange(Range(mi.base_address, mi.region_size))) | 449 if (range.OverlapsRange(Range(mi.BaseAddress, mi.RegionSize))) |
Mark Mentovai
2015/10/07 01:17:24
Since these types are now not WinVMAddress in name
scottmg
2015/10/07 18:19:17
Done.
| |
450 overlapping.push_back(mi); | 450 overlapping.push_back(mi); |
451 } | 451 } |
452 if (overlapping.empty()) | 452 if (overlapping.empty()) |
453 return std::vector<Range>(); | 453 return std::vector<Range>(); |
454 | 454 |
455 // For the first and last, trim to the boundary of the incoming range. | 455 // For the first and last, trim to the boundary of the incoming range. |
456 ProcessInfo::MemoryInfo& front = overlapping.front(); | 456 MEMORY_BASIC_INFORMATION64& front = overlapping.front(); |
457 WinVMAddress original_front_base_address = front.base_address; | 457 WinVMAddress original_front_base_address = front.BaseAddress; |
458 front.base_address = std::max(front.base_address, range.base()); | 458 front.BaseAddress = std::max(front.BaseAddress, range.base()); |
459 front.region_size = | 459 front.RegionSize = |
460 (original_front_base_address + front.region_size) - front.base_address; | 460 (original_front_base_address + front.RegionSize) - front.BaseAddress; |
461 | 461 |
462 ProcessInfo::MemoryInfo& back = overlapping.back(); | 462 MEMORY_BASIC_INFORMATION64& back = overlapping.back(); |
463 WinVMAddress back_end = back.base_address + back.region_size; | 463 WinVMAddress back_end = back.BaseAddress + back.RegionSize; |
464 back.region_size = std::min(range.end(), back_end) - back.base_address; | 464 back.RegionSize = std::min(range.end(), back_end) - back.BaseAddress; |
465 | 465 |
466 // Discard all non-accessible. | 466 // Discard all non-accessible. |
467 overlapping.erase(std::remove_if(overlapping.begin(), | 467 overlapping.erase(std::remove_if(overlapping.begin(), |
468 overlapping.end(), | 468 overlapping.end(), |
469 [](const ProcessInfo::MemoryInfo& mi) { | 469 [](const MEMORY_BASIC_INFORMATION64& mbi) { |
470 return !RegionIsAccessible(mi); | 470 return !RegionIsAccessible(mbi); |
471 }), | 471 }), |
472 overlapping.end()); | 472 overlapping.end()); |
473 if (overlapping.empty()) | 473 if (overlapping.empty()) |
474 return std::vector<Range>(); | 474 return std::vector<Range>(); |
475 | 475 |
476 // Convert to return type. | 476 // Convert to return type. |
477 std::vector<Range> as_ranges; | 477 std::vector<Range> as_ranges; |
478 for (const auto& mi : overlapping) { | 478 for (const auto& mi : overlapping) { |
479 as_ranges.push_back(Range(mi.base_address, mi.region_size)); | 479 as_ranges.push_back(Range(mi.BaseAddress, mi.RegionSize)); |
480 DCHECK(as_ranges.back().IsValid()); | 480 DCHECK(as_ranges.back().IsValid()); |
481 } | 481 } |
482 | 482 |
483 // Coalesce remaining regions. | 483 // Coalesce remaining regions. |
484 std::vector<Range> result; | 484 std::vector<Range> result; |
485 result.push_back(as_ranges[0]); | 485 result.push_back(as_ranges[0]); |
486 for (size_t i = 1; i < as_ranges.size(); ++i) { | 486 for (size_t i = 1; i < as_ranges.size(); ++i) { |
487 if (result.back().end() == as_ranges[i].base()) { | 487 if (result.back().end() == as_ranges[i].base()) { |
488 result.back().SetRange(result.back().base(), | 488 result.back().SetRange(result.back().base(), |
489 result.back().size() + as_ranges[i].size()); | 489 result.back().size() + as_ranges[i].size()); |
490 } else { | 490 } else { |
491 result.push_back(as_ranges[i]); | 491 result.push_back(as_ranges[i]); |
492 } | 492 } |
493 DCHECK(result.back().IsValid()); | 493 DCHECK(result.back().IsValid()); |
494 } | 494 } |
495 | 495 |
496 return result; | 496 return result; |
497 } | 497 } |
498 | 498 |
499 } // namespace crashpad | 499 } // namespace crashpad |
OLD | NEW |