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 size_t padded_length = (win_certificate->dwLength + 7) & ~0x7; |
| 185 data_size -= padded_length; |
| 186 data += padded_length; |
| 187 } |
| 188 return true; |
| 189 } |
| 190 |
159 void PeImageReader::Clear() { | 191 void PeImageReader::Clear() { |
160 image_data_ = NULL; | 192 image_data_ = NULL; |
161 image_size_ = 0; | 193 image_size_ = 0; |
162 validation_state_ = 0; | 194 validation_state_ = 0; |
163 optional_header_.reset(); | 195 optional_header_.reset(); |
164 } | 196 } |
165 | 197 |
166 bool PeImageReader::ValidateDosHeader() { | 198 bool PeImageReader::ValidateDosHeader() { |
167 const IMAGE_DOS_HEADER* dos_header = NULL; | 199 const IMAGE_DOS_HEADER* dos_header = NULL; |
168 if (!GetStructureAt(0, &dos_header) || | 200 if (!GetStructureAt(0, &dos_header) || |
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
302 } | 334 } |
303 return NULL; | 335 return NULL; |
304 } | 336 } |
305 | 337 |
306 const uint8_t* PeImageReader::GetImageData(size_t index, size_t* data_length) { | 338 const uint8_t* PeImageReader::GetImageData(size_t index, size_t* data_length) { |
307 // Get the requested directory entry. | 339 // Get the requested directory entry. |
308 const IMAGE_DATA_DIRECTORY* entry = GetDataDirectoryEntryAt(index); | 340 const IMAGE_DATA_DIRECTORY* entry = GetDataDirectoryEntryAt(index); |
309 if (!entry) | 341 if (!entry) |
310 return NULL; | 342 return NULL; |
311 | 343 |
| 344 // The entry for the certificate table is special in that its address is a |
| 345 // file pointer rather than an RVA. |
| 346 if (index == IMAGE_DIRECTORY_ENTRY_SECURITY) { |
| 347 // Does the data fit within the file. |
| 348 if (entry->VirtualAddress > image_size_ || |
| 349 image_size_ - entry->VirtualAddress < entry->Size) { |
| 350 return nullptr; |
| 351 } |
| 352 *data_length = entry->Size; |
| 353 return image_data_ + entry->VirtualAddress; |
| 354 } |
| 355 |
312 // Find the section containing the data. | 356 // Find the section containing the data. |
313 const IMAGE_SECTION_HEADER* header = | 357 const IMAGE_SECTION_HEADER* header = |
314 FindSectionFromRva(entry->VirtualAddress); | 358 FindSectionFromRva(entry->VirtualAddress); |
315 if (!header) | 359 if (!header) |
316 return NULL; | 360 return NULL; |
317 | 361 |
318 // Does the data fit within the section when mapped? | 362 // Does the data fit within the section when mapped? |
319 size_t data_offset = entry->VirtualAddress - header->VirtualAddress; | 363 size_t data_offset = entry->VirtualAddress - header->VirtualAddress; |
320 if (entry->Size > (header->Misc.VirtualSize - data_offset)) | 364 if (entry->Size > (header->Misc.VirtualSize - data_offset)) |
321 return NULL; | 365 return NULL; |
322 | 366 |
323 // Is the data entirely present on disk (if not it's zeroed out when loaded)? | 367 // Is the data entirely present on disk (if not it's zeroed out when loaded)? |
324 if (data_offset >= header->SizeOfRawData || | 368 if (data_offset >= header->SizeOfRawData || |
325 header->SizeOfRawData - data_offset < entry->Size) { | 369 header->SizeOfRawData - data_offset < entry->Size) { |
326 return NULL; | 370 return NULL; |
327 } | 371 } |
328 | 372 |
329 *data_length = entry->Size; | 373 *data_length = entry->Size; |
330 return image_data_ + header->PointerToRawData + data_offset; | 374 return image_data_ + header->PointerToRawData + data_offset; |
331 } | 375 } |
332 | 376 |
333 } // namespace safe_browsing | 377 } // namespace safe_browsing |
OLD | NEW |