| 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 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 136 } else { | 136 } else { |
| 137 return ReadDebugDirectoryInformation<IMAGE_NT_HEADERS32>( | 137 return ReadDebugDirectoryInformation<IMAGE_NT_HEADERS32>( |
| 138 uuid, age, pdbname); | 138 uuid, age, pdbname); |
| 139 } | 139 } |
| 140 } | 140 } |
| 141 | 141 |
| 142 template <class NtHeadersType> | 142 template <class NtHeadersType> |
| 143 bool PEImageReader::ReadDebugDirectoryInformation(UUID* uuid, | 143 bool PEImageReader::ReadDebugDirectoryInformation(UUID* uuid, |
| 144 DWORD* age, | 144 DWORD* age, |
| 145 std::string* pdbname) const { | 145 std::string* pdbname) const { |
| 146 WinVMAddress nt_headers_address; | |
| 147 NtHeadersType nt_headers; | 146 NtHeadersType nt_headers; |
| 148 if (!ReadNtHeaders(&nt_headers_address, &nt_headers)) | 147 if (!ReadNtHeaders(&nt_headers, nullptr)) |
| 149 return false; | 148 return false; |
| 150 | 149 |
| 150 if (nt_headers.FileHeader.SizeOfOptionalHeader < |
| 151 offsetof(decltype(nt_headers.OptionalHeader), |
| 152 DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG]) + |
| 153 sizeof(nt_headers.OptionalHeader |
| 154 .DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG]) || |
| 155 nt_headers.OptionalHeader.NumberOfRvaAndSizes <= |
| 156 IMAGE_DIRECTORY_ENTRY_DEBUG) { |
| 157 return false; |
| 158 } |
| 159 |
| 151 const IMAGE_DATA_DIRECTORY& data_directory = | 160 const IMAGE_DATA_DIRECTORY& data_directory = |
| 152 nt_headers.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG]; | 161 nt_headers.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG]; |
| 153 if (data_directory.VirtualAddress == 0 || data_directory.Size == 0) | 162 if (data_directory.VirtualAddress == 0 || data_directory.Size == 0) |
| 154 return false; | 163 return false; |
| 155 IMAGE_DEBUG_DIRECTORY debug_directory; | 164 IMAGE_DEBUG_DIRECTORY debug_directory; |
| 156 if (data_directory.Size % sizeof(debug_directory) != 0) | 165 if (data_directory.Size % sizeof(debug_directory) != 0) |
| 157 return false; | 166 return false; |
| 158 for (size_t offset = 0; offset < data_directory.Size; | 167 for (size_t offset = 0; offset < data_directory.Size; |
| 159 offset += sizeof(debug_directory)) { | 168 offset += sizeof(debug_directory)) { |
| 160 if (!CheckedReadMemory(Address() + data_directory.VirtualAddress + offset, | 169 if (!CheckedReadMemory(Address() + data_directory.VirtualAddress + offset, |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 195 // where the binary was linked. We have no idea what that was, so we just | 204 // where the binary was linked. We have no idea what that was, so we just |
| 196 // assume ASCII. | 205 // assume ASCII. |
| 197 *pdbname = std::string(reinterpret_cast<char*>(&codeview->pdb_name[0])); | 206 *pdbname = std::string(reinterpret_cast<char*>(&codeview->pdb_name[0])); |
| 198 return true; | 207 return true; |
| 199 } | 208 } |
| 200 | 209 |
| 201 return false; | 210 return false; |
| 202 } | 211 } |
| 203 | 212 |
| 204 template <class NtHeadersType> | 213 template <class NtHeadersType> |
| 205 bool PEImageReader::ReadNtHeaders(WinVMAddress* nt_headers_address, | 214 bool PEImageReader::ReadNtHeaders(NtHeadersType* nt_headers, |
| 206 NtHeadersType* nt_headers) const { | 215 WinVMAddress* nt_headers_address) const { |
| 207 IMAGE_DOS_HEADER dos_header; | 216 IMAGE_DOS_HEADER dos_header; |
| 208 if (!CheckedReadMemory(Address(), sizeof(IMAGE_DOS_HEADER), &dos_header)) { | 217 if (!CheckedReadMemory(Address(), sizeof(IMAGE_DOS_HEADER), &dos_header)) { |
| 209 LOG(WARNING) << "could not read dos header of " << module_name_; | 218 LOG(WARNING) << "could not read dos header of " << module_name_; |
| 210 return false; | 219 return false; |
| 211 } | 220 } |
| 212 | 221 |
| 213 if (dos_header.e_magic != IMAGE_DOS_SIGNATURE) { | 222 if (dos_header.e_magic != IMAGE_DOS_SIGNATURE) { |
| 214 LOG(WARNING) << "invalid e_magic in dos header of " << module_name_; | 223 LOG(WARNING) << "invalid e_magic in dos header of " << module_name_; |
| 215 return false; | 224 return false; |
| 216 } | 225 } |
| 217 | 226 |
| 218 *nt_headers_address = Address() + dos_header.e_lfanew; | 227 WinVMAddress local_nt_headers_address = Address() + dos_header.e_lfanew; |
| 219 if (!CheckedReadMemory( | 228 if (!CheckedReadMemory( |
| 220 *nt_headers_address, sizeof(NtHeadersType), nt_headers)) { | 229 local_nt_headers_address, sizeof(NtHeadersType), nt_headers)) { |
| 221 LOG(WARNING) << "could not read nt headers of " << module_name_; | 230 LOG(WARNING) << "could not read nt headers of " << module_name_; |
| 222 return false; | 231 return false; |
| 223 } | 232 } |
| 224 | 233 |
| 225 if (nt_headers->Signature != IMAGE_NT_SIGNATURE) { | 234 if (nt_headers->Signature != IMAGE_NT_SIGNATURE) { |
| 226 LOG(WARNING) << "invalid signature in nt headers of " << module_name_; | 235 LOG(WARNING) << "invalid signature in nt headers of " << module_name_; |
| 227 return false; | 236 return false; |
| 228 } | 237 } |
| 229 | 238 |
| 239 if (nt_headers_address) |
| 240 *nt_headers_address = local_nt_headers_address; |
| 241 |
| 230 return true; | 242 return true; |
| 231 } | 243 } |
| 232 | 244 |
| 233 template <class NtHeadersType> | 245 template <class NtHeadersType> |
| 234 bool PEImageReader::GetSectionByName(const std::string& name, | 246 bool PEImageReader::GetSectionByName(const std::string& name, |
| 235 IMAGE_SECTION_HEADER* section) const { | 247 IMAGE_SECTION_HEADER* section) const { |
| 236 if (name.size() > sizeof(section->Name)) { | 248 if (name.size() > sizeof(section->Name)) { |
| 237 LOG(WARNING) << "supplied section name too long " << name; | 249 LOG(WARNING) << "supplied section name too long " << name; |
| 238 return false; | 250 return false; |
| 239 } | 251 } |
| 240 | 252 |
| 253 NtHeadersType nt_headers; |
| 241 WinVMAddress nt_headers_address; | 254 WinVMAddress nt_headers_address; |
| 242 NtHeadersType nt_headers; | 255 if (!ReadNtHeaders(&nt_headers, &nt_headers_address)) |
| 243 if (!ReadNtHeaders(&nt_headers_address, &nt_headers)) | |
| 244 return false; | 256 return false; |
| 245 | 257 |
| 246 WinVMAddress first_section_address = | 258 WinVMAddress first_section_address = |
| 247 nt_headers_address + offsetof(NtHeadersType, OptionalHeader) + | 259 nt_headers_address + offsetof(NtHeadersType, OptionalHeader) + |
| 248 nt_headers.FileHeader.SizeOfOptionalHeader; | 260 nt_headers.FileHeader.SizeOfOptionalHeader; |
| 249 for (DWORD i = 0; i < nt_headers.FileHeader.NumberOfSections; ++i) { | 261 for (DWORD i = 0; i < nt_headers.FileHeader.NumberOfSections; ++i) { |
| 250 WinVMAddress section_address = | 262 WinVMAddress section_address = |
| 251 first_section_address + sizeof(IMAGE_SECTION_HEADER) * i; | 263 first_section_address + sizeof(IMAGE_SECTION_HEADER) * i; |
| 252 if (!CheckedReadMemory( | 264 if (!CheckedReadMemory( |
| 253 section_address, sizeof(IMAGE_SECTION_HEADER), section)) { | 265 section_address, sizeof(IMAGE_SECTION_HEADER), section)) { |
| (...skipping 29 matching lines...) Expand all Loading... |
| 283 // Explicit instantiations with the only 2 valid template arguments to avoid | 295 // Explicit instantiations with the only 2 valid template arguments to avoid |
| 284 // putting the body of the function in the header. | 296 // putting the body of the function in the header. |
| 285 template bool PEImageReader::GetCrashpadInfo<process_types::internal::Traits32>( | 297 template bool PEImageReader::GetCrashpadInfo<process_types::internal::Traits32>( |
| 286 process_types::CrashpadInfo<process_types::internal::Traits32>* | 298 process_types::CrashpadInfo<process_types::internal::Traits32>* |
| 287 crashpad_info) const; | 299 crashpad_info) const; |
| 288 template bool PEImageReader::GetCrashpadInfo<process_types::internal::Traits64>( | 300 template bool PEImageReader::GetCrashpadInfo<process_types::internal::Traits64>( |
| 289 process_types::CrashpadInfo<process_types::internal::Traits64>* | 301 process_types::CrashpadInfo<process_types::internal::Traits64>* |
| 290 crashpad_info) const; | 302 crashpad_info) const; |
| 291 | 303 |
| 292 } // namespace crashpad | 304 } // namespace crashpad |
| OLD | NEW |