| 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 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 63 | 63 |
| 64 INITIALIZATION_STATE_SET_VALID(initialized_); | 64 INITIALIZATION_STATE_SET_VALID(initialized_); |
| 65 return true; | 65 return true; |
| 66 } | 66 } |
| 67 | 67 |
| 68 bool PEImageReader::GetCrashpadInfo( | 68 bool PEImageReader::GetCrashpadInfo( |
| 69 process_types::CrashpadInfo* crashpad_info) const { | 69 process_types::CrashpadInfo* crashpad_info) const { |
| 70 INITIALIZATION_STATE_DCHECK_VALID(initialized_); | 70 INITIALIZATION_STATE_DCHECK_VALID(initialized_); |
| 71 | 71 |
| 72 IMAGE_SECTION_HEADER section; | 72 IMAGE_SECTION_HEADER section; |
| 73 if (!GetSectionByName("CPADinfo", §ion)) | 73 if (process_reader_->Is64Bit()) { |
| 74 return false; | 74 if (!GetSectionByName<IMAGE_NT_HEADERS64>("CPADinfo", §ion)) |
| 75 return false; |
| 76 } else { |
| 77 if (!GetSectionByName<IMAGE_NT_HEADERS32>("CPADinfo", §ion)) |
| 78 return false; |
| 79 } |
| 75 | 80 |
| 76 if (section.Misc.VirtualSize < sizeof(process_types::CrashpadInfo)) { | 81 if (section.Misc.VirtualSize < sizeof(process_types::CrashpadInfo)) { |
| 77 LOG(WARNING) << "small crashpad info section size " | 82 LOG(WARNING) << "small crashpad info section size " |
| 78 << section.Misc.VirtualSize << ", " << module_name_; | 83 << section.Misc.VirtualSize << ", " << module_name_; |
| 79 return false; | 84 return false; |
| 80 } | 85 } |
| 81 | 86 |
| 82 WinVMAddress crashpad_info_address = Address() + section.VirtualAddress; | 87 WinVMAddress crashpad_info_address = Address() + section.VirtualAddress; |
| 83 CheckedWinAddressRange crashpad_info_range(process_reader_->Is64Bit(), | 88 CheckedWinAddressRange crashpad_info_range(process_reader_->Is64Bit(), |
| 84 crashpad_info_address, | 89 crashpad_info_address, |
| (...skipping 22 matching lines...) Expand all Loading... |
| 107 crashpad_info->version < 1) { | 112 crashpad_info->version < 1) { |
| 108 LOG(WARNING) << "unexpected crashpad info data " << module_name_; | 113 LOG(WARNING) << "unexpected crashpad info data " << module_name_; |
| 109 return false; | 114 return false; |
| 110 } | 115 } |
| 111 | 116 |
| 112 return true; | 117 return true; |
| 113 } | 118 } |
| 114 | 119 |
| 115 bool PEImageReader::DebugDirectoryInformation(UUID* uuid, | 120 bool PEImageReader::DebugDirectoryInformation(UUID* uuid, |
| 116 DWORD* age, | 121 DWORD* age, |
| 117 std::string* pdbname) { | 122 std::string* pdbname) const { |
| 123 if (process_reader_->Is64Bit()) { |
| 124 return ReadDebugDirectoryInformation<IMAGE_NT_HEADERS64>( |
| 125 uuid, age, pdbname); |
| 126 } else { |
| 127 return ReadDebugDirectoryInformation<IMAGE_NT_HEADERS32>( |
| 128 uuid, age, pdbname); |
| 129 } |
| 130 } |
| 131 |
| 132 template <class NtHeadersType> |
| 133 bool PEImageReader::ReadDebugDirectoryInformation(UUID* uuid, |
| 134 DWORD* age, |
| 135 std::string* pdbname) const { |
| 118 WinVMAddress nt_headers_address; | 136 WinVMAddress nt_headers_address; |
| 119 IMAGE_NT_HEADERS nt_headers; | 137 NtHeadersType nt_headers; |
| 120 if (!ReadNtHeaders(&nt_headers_address, &nt_headers)) | 138 if (!ReadNtHeaders(&nt_headers_address, &nt_headers)) |
| 121 return false; | 139 return false; |
| 122 | 140 |
| 123 const IMAGE_DATA_DIRECTORY& data_directory = | 141 const IMAGE_DATA_DIRECTORY& data_directory = |
| 124 nt_headers.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG]; | 142 nt_headers.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG]; |
| 125 if (data_directory.VirtualAddress == 0 || data_directory.Size == 0) | 143 if (data_directory.VirtualAddress == 0 || data_directory.Size == 0) |
| 126 return false; | 144 return false; |
| 127 IMAGE_DEBUG_DIRECTORY debug_directory; | 145 IMAGE_DEBUG_DIRECTORY debug_directory; |
| 128 if (data_directory.Size % sizeof(debug_directory) != 0) | 146 if (data_directory.Size % sizeof(debug_directory) != 0) |
| 129 return false; | 147 return false; |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 166 // This is a NUL-terminated string encoded in the codepage of the system | 184 // This is a NUL-terminated string encoded in the codepage of the system |
| 167 // where the binary was linked. We have no idea what that was, so we just | 185 // where the binary was linked. We have no idea what that was, so we just |
| 168 // assume ASCII. | 186 // assume ASCII. |
| 169 *pdbname = std::string(reinterpret_cast<char*>(&codeview->pdb_name[0])); | 187 *pdbname = std::string(reinterpret_cast<char*>(&codeview->pdb_name[0])); |
| 170 return true; | 188 return true; |
| 171 } | 189 } |
| 172 | 190 |
| 173 return false; | 191 return false; |
| 174 } | 192 } |
| 175 | 193 |
| 176 // TODO(scottmg): This needs to be made cross-bitness supporting. | 194 template <class NtHeadersType> |
| 177 bool PEImageReader::ReadNtHeaders(WinVMAddress* nt_headers_address, | 195 bool PEImageReader::ReadNtHeaders(WinVMAddress* nt_headers_address, |
| 178 IMAGE_NT_HEADERS* nt_headers) const { | 196 NtHeadersType* nt_headers) const { |
| 179 IMAGE_DOS_HEADER dos_header; | 197 IMAGE_DOS_HEADER dos_header; |
| 180 if (!CheckedReadMemory(Address(), sizeof(IMAGE_DOS_HEADER), &dos_header)) { | 198 if (!CheckedReadMemory(Address(), sizeof(IMAGE_DOS_HEADER), &dos_header)) { |
| 181 LOG(WARNING) << "could not read dos header of " << module_name_; | 199 LOG(WARNING) << "could not read dos header of " << module_name_; |
| 182 return false; | 200 return false; |
| 183 } | 201 } |
| 184 | 202 |
| 185 if (dos_header.e_magic != IMAGE_DOS_SIGNATURE) { | 203 if (dos_header.e_magic != IMAGE_DOS_SIGNATURE) { |
| 186 LOG(WARNING) << "invalid e_magic in dos header of " << module_name_; | 204 LOG(WARNING) << "invalid e_magic in dos header of " << module_name_; |
| 187 return false; | 205 return false; |
| 188 } | 206 } |
| 189 | 207 |
| 190 *nt_headers_address = Address() + dos_header.e_lfanew; | 208 *nt_headers_address = Address() + dos_header.e_lfanew; |
| 191 if (!CheckedReadMemory( | 209 if (!CheckedReadMemory( |
| 192 *nt_headers_address, sizeof(IMAGE_NT_HEADERS), nt_headers)) { | 210 *nt_headers_address, sizeof(NtHeadersType), nt_headers)) { |
| 193 LOG(WARNING) << "could not read nt headers of " << module_name_; | 211 LOG(WARNING) << "could not read nt headers of " << module_name_; |
| 194 return false; | 212 return false; |
| 195 } | 213 } |
| 196 | 214 |
| 197 if (nt_headers->Signature != IMAGE_NT_SIGNATURE) { | 215 if (nt_headers->Signature != IMAGE_NT_SIGNATURE) { |
| 198 LOG(WARNING) << "invalid signature in nt headers of " << module_name_; | 216 LOG(WARNING) << "invalid signature in nt headers of " << module_name_; |
| 199 return false; | 217 return false; |
| 200 } | 218 } |
| 201 | 219 |
| 202 return true; | 220 return true; |
| 203 } | 221 } |
| 204 | 222 |
| 223 template <class NtHeadersType> |
| 205 bool PEImageReader::GetSectionByName(const std::string& name, | 224 bool PEImageReader::GetSectionByName(const std::string& name, |
| 206 IMAGE_SECTION_HEADER* section) const { | 225 IMAGE_SECTION_HEADER* section) const { |
| 207 if (name.size() > sizeof(section->Name)) { | 226 if (name.size() > sizeof(section->Name)) { |
| 208 LOG(WARNING) << "supplied section name too long " << name; | 227 LOG(WARNING) << "supplied section name too long " << name; |
| 209 return false; | 228 return false; |
| 210 } | 229 } |
| 211 | 230 |
| 212 WinVMAddress nt_headers_address; | 231 WinVMAddress nt_headers_address; |
| 213 IMAGE_NT_HEADERS nt_headers; | 232 NtHeadersType nt_headers; |
| 214 if (!ReadNtHeaders(&nt_headers_address, &nt_headers)) | 233 if (!ReadNtHeaders(&nt_headers_address, &nt_headers)) |
| 215 return false; | 234 return false; |
| 216 | 235 |
| 217 WinVMAddress first_section_address = | 236 WinVMAddress first_section_address = |
| 218 nt_headers_address + offsetof(IMAGE_NT_HEADERS, OptionalHeader) + | 237 nt_headers_address + offsetof(NtHeadersType, OptionalHeader) + |
| 219 nt_headers.FileHeader.SizeOfOptionalHeader; | 238 nt_headers.FileHeader.SizeOfOptionalHeader; |
| 220 for (DWORD i = 0; i < nt_headers.FileHeader.NumberOfSections; ++i) { | 239 for (DWORD i = 0; i < nt_headers.FileHeader.NumberOfSections; ++i) { |
| 221 WinVMAddress section_address = | 240 WinVMAddress section_address = |
| 222 first_section_address + sizeof(IMAGE_SECTION_HEADER) * i; | 241 first_section_address + sizeof(IMAGE_SECTION_HEADER) * i; |
| 223 if (!CheckedReadMemory( | 242 if (!CheckedReadMemory( |
| 224 section_address, sizeof(IMAGE_SECTION_HEADER), section)) { | 243 section_address, sizeof(IMAGE_SECTION_HEADER), section)) { |
| 225 LOG(WARNING) << "could not read section " << i << " of " << module_name_; | 244 LOG(WARNING) << "could not read section " << i << " of " << module_name_; |
| 226 return false; | 245 return false; |
| 227 } | 246 } |
| 228 if (strncmp(reinterpret_cast<const char*>(section->Name), | 247 if (strncmp(reinterpret_cast<const char*>(section->Name), |
| (...skipping 16 matching lines...) Expand all Loading... |
| 245 } | 264 } |
| 246 if (!module_range_.ContainsRange(read_range)) { | 265 if (!module_range_.ContainsRange(read_range)) { |
| 247 LOG(WARNING) << "attempt to read outside of module " << module_name_ | 266 LOG(WARNING) << "attempt to read outside of module " << module_name_ |
| 248 << " at range: " << RangeToString(read_range); | 267 << " at range: " << RangeToString(read_range); |
| 249 return false; | 268 return false; |
| 250 } | 269 } |
| 251 return process_reader_->ReadMemory(address, size, into); | 270 return process_reader_->ReadMemory(address, size, into); |
| 252 } | 271 } |
| 253 | 272 |
| 254 } // namespace crashpad | 273 } // namespace crashpad |
| OLD | NEW |