| 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 |