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 |