Index: chrome/common/safe_browsing/pe_image_reader_win.cc |
diff --git a/chrome/common/safe_browsing/pe_image_reader_win.cc b/chrome/common/safe_browsing/pe_image_reader_win.cc |
index 0e88eba466d8242b941daaaff805f1e4ff4ebbfb..16185ba7cef18fb87f575fdbdc8e23ef42344c42 100644 |
--- a/chrome/common/safe_browsing/pe_image_reader_win.cc |
+++ b/chrome/common/safe_browsing/pe_image_reader_win.cc |
@@ -4,6 +4,8 @@ |
#include "chrome/common/safe_browsing/pe_image_reader_win.h" |
+#include <wintrust.h> |
+ |
#include "base/logging.h" |
namespace safe_browsing { |
@@ -156,6 +158,36 @@ const IMAGE_DEBUG_DIRECTORY* PeImageReader::GetDebugEntry( |
return &entry; |
} |
+bool PeImageReader::EnumCertificates(EnumCertificatesCallback callback, |
+ void* context) { |
+ size_t data_size = 0; |
+ const uint8_t* data = GetImageData(IMAGE_DIRECTORY_ENTRY_SECURITY, |
+ &data_size); |
+ if (!data) |
+ return false; // Certificate table is out of bounds. |
+ const size_t kWinCertificateSize = offsetof(WIN_CERTIFICATE, bCertificate); |
+ while (data_size) { |
+ const WIN_CERTIFICATE* win_certificate = |
+ reinterpret_cast<const WIN_CERTIFICATE*>(data); |
+ if (kWinCertificateSize > data_size || |
+ kWinCertificateSize > win_certificate->dwLength || |
+ win_certificate->dwLength > data_size) { |
+ return false; |
+ } |
+ if (!(*callback)(win_certificate->wRevision, |
+ win_certificate->wCertificateType, |
+ &win_certificate->bCertificate[0], |
+ win_certificate->dwLength - kWinCertificateSize, |
+ context)) { |
+ return false; |
+ } |
+ size_t padded_length = (win_certificate->dwLength + 7) & ~0x7; |
+ data_size -= padded_length; |
+ data += padded_length; |
+ } |
+ return true; |
+} |
+ |
void PeImageReader::Clear() { |
image_data_ = NULL; |
image_size_ = 0; |
@@ -309,6 +341,18 @@ const uint8_t* PeImageReader::GetImageData(size_t index, size_t* data_length) { |
if (!entry) |
return NULL; |
+ // The entry for the certificate table is special in that its address is a |
+ // file pointer rather than an RVA. |
+ if (index == IMAGE_DIRECTORY_ENTRY_SECURITY) { |
+ // Does the data fit within the file. |
+ if (entry->VirtualAddress > image_size_ || |
+ image_size_ - entry->VirtualAddress < entry->Size) { |
+ return nullptr; |
+ } |
+ *data_length = entry->Size; |
+ return image_data_ + entry->VirtualAddress; |
+ } |
+ |
// Find the section containing the data. |
const IMAGE_SECTION_HEADER* header = |
FindSectionFromRva(entry->VirtualAddress); |