Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/common/safe_browsing/pe_image_reader_win.h" | 5 #include "chrome/common/safe_browsing/pe_image_reader_win.h" |
| 6 | 6 |
| 7 #include <wintrust.h> | |
| 8 | |
| 7 #include "base/logging.h" | 9 #include "base/logging.h" |
| 8 | 10 |
| 9 namespace safe_browsing { | 11 namespace safe_browsing { |
| 10 | 12 |
| 11 // A class template of traits pertaining to IMAGE_OPTIONAL_HEADER{32,64}. | 13 // A class template of traits pertaining to IMAGE_OPTIONAL_HEADER{32,64}. |
| 12 template<class HEADER_TYPE> | 14 template<class HEADER_TYPE> |
| 13 struct OptionalHeaderTraits { | 15 struct OptionalHeaderTraits { |
| 14 }; | 16 }; |
| 15 | 17 |
| 16 template<> | 18 template<> |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 149 | 151 |
| 150 const IMAGE_DEBUG_DIRECTORY& entry = entries[index]; | 152 const IMAGE_DEBUG_DIRECTORY& entry = entries[index]; |
| 151 const uint8_t* debug_data = NULL; | 153 const uint8_t* debug_data = NULL; |
| 152 if (GetStructureAt(entry.PointerToRawData, entry.SizeOfData, &debug_data)) { | 154 if (GetStructureAt(entry.PointerToRawData, entry.SizeOfData, &debug_data)) { |
| 153 *raw_data = debug_data; | 155 *raw_data = debug_data; |
| 154 *raw_data_size = entry.SizeOfData; | 156 *raw_data_size = entry.SizeOfData; |
| 155 } | 157 } |
| 156 return &entry; | 158 return &entry; |
| 157 } | 159 } |
| 158 | 160 |
| 161 bool PeImageReader::EnumCertificates(EnumCertificatesCallback callback, | |
| 162 void* context) { | |
| 163 size_t data_size = 0; | |
| 164 const uint8_t* data = GetImageData(IMAGE_DIRECTORY_ENTRY_SECURITY, | |
| 165 &data_size); | |
| 166 if (!data) | |
| 167 return false; // Certificate table is out of bounds. | |
| 168 const size_t kWinCertificateSize = offsetof(WIN_CERTIFICATE, bCertificate); | |
| 169 while (data_size) { | |
| 170 const WIN_CERTIFICATE* win_certificate = | |
| 171 reinterpret_cast<const WIN_CERTIFICATE*>(data); | |
| 172 if (kWinCertificateSize > data_size || | |
| 173 kWinCertificateSize > win_certificate->dwLength || | |
| 174 win_certificate->dwLength > data_size) { | |
| 175 return false; | |
| 176 } | |
| 177 if (!(*callback)(win_certificate->wRevision, | |
| 178 win_certificate->wCertificateType, | |
| 179 &win_certificate->bCertificate[0], | |
| 180 win_certificate->dwLength - kWinCertificateSize, | |
| 181 context)) { | |
| 182 return false; | |
| 183 } | |
| 184 data_size -= (win_certificate->dwLength + 7) & ~0x7; | |
|
mattm
2015/04/01 22:49:52
data needs to be incremented also?
grt (UTC plus 2)
2015/04/02 02:59:36
Yes. Nice catch.
| |
| 185 } | |
| 186 return true; | |
| 187 } | |
| 188 | |
| 159 void PeImageReader::Clear() { | 189 void PeImageReader::Clear() { |
| 160 image_data_ = NULL; | 190 image_data_ = NULL; |
| 161 image_size_ = 0; | 191 image_size_ = 0; |
| 162 validation_state_ = 0; | 192 validation_state_ = 0; |
| 163 optional_header_.reset(); | 193 optional_header_.reset(); |
| 164 } | 194 } |
| 165 | 195 |
| 166 bool PeImageReader::ValidateDosHeader() { | 196 bool PeImageReader::ValidateDosHeader() { |
| 167 const IMAGE_DOS_HEADER* dos_header = NULL; | 197 const IMAGE_DOS_HEADER* dos_header = NULL; |
| 168 if (!GetStructureAt(0, &dos_header) || | 198 if (!GetStructureAt(0, &dos_header) || |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 302 } | 332 } |
| 303 return NULL; | 333 return NULL; |
| 304 } | 334 } |
| 305 | 335 |
| 306 const uint8_t* PeImageReader::GetImageData(size_t index, size_t* data_length) { | 336 const uint8_t* PeImageReader::GetImageData(size_t index, size_t* data_length) { |
| 307 // Get the requested directory entry. | 337 // Get the requested directory entry. |
| 308 const IMAGE_DATA_DIRECTORY* entry = GetDataDirectoryEntryAt(index); | 338 const IMAGE_DATA_DIRECTORY* entry = GetDataDirectoryEntryAt(index); |
| 309 if (!entry) | 339 if (!entry) |
| 310 return NULL; | 340 return NULL; |
| 311 | 341 |
| 342 // The entry for the certificate table is special in that its addres is a file | |
|
mattm
2015/04/01 22:49:52
address
grt (UTC plus 2)
2015/04/02 02:59:36
Done.
| |
| 343 // pointer rather than an RVA. | |
| 344 if (index == IMAGE_DIRECTORY_ENTRY_SECURITY) { | |
| 345 // Does the data fit within the file. | |
| 346 if (entry->VirtualAddress > image_size_ || | |
| 347 image_size_ - entry->VirtualAddress < entry->Size) { | |
| 348 return nullptr; | |
| 349 } | |
| 350 *data_length = entry->Size; | |
| 351 return image_data_ + entry->VirtualAddress; | |
| 352 } | |
| 353 | |
| 312 // Find the section containing the data. | 354 // Find the section containing the data. |
| 313 const IMAGE_SECTION_HEADER* header = | 355 const IMAGE_SECTION_HEADER* header = |
| 314 FindSectionFromRva(entry->VirtualAddress); | 356 FindSectionFromRva(entry->VirtualAddress); |
| 315 if (!header) | 357 if (!header) |
| 316 return NULL; | 358 return NULL; |
| 317 | 359 |
| 318 // Does the data fit within the section when mapped? | 360 // Does the data fit within the section when mapped? |
| 319 size_t data_offset = entry->VirtualAddress - header->VirtualAddress; | 361 size_t data_offset = entry->VirtualAddress - header->VirtualAddress; |
| 320 if (entry->Size > (header->Misc.VirtualSize - data_offset)) | 362 if (entry->Size > (header->Misc.VirtualSize - data_offset)) |
| 321 return NULL; | 363 return NULL; |
| 322 | 364 |
| 323 // Is the data entirely present on disk (if not it's zeroed out when loaded)? | 365 // Is the data entirely present on disk (if not it's zeroed out when loaded)? |
| 324 if (data_offset >= header->SizeOfRawData || | 366 if (data_offset >= header->SizeOfRawData || |
| 325 header->SizeOfRawData - data_offset < entry->Size) { | 367 header->SizeOfRawData - data_offset < entry->Size) { |
| 326 return NULL; | 368 return NULL; |
| 327 } | 369 } |
| 328 | 370 |
| 329 *data_length = entry->Size; | 371 *data_length = entry->Size; |
| 330 return image_data_ + header->PointerToRawData + data_offset; | 372 return image_data_ + header->PointerToRawData + data_offset; |
| 331 } | 373 } |
| 332 | 374 |
| 333 } // namespace safe_browsing | 375 } // namespace safe_browsing |
| OLD | NEW |