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/binary_feature_extractor.h" | 5 #include "chrome/common/safe_browsing/binary_feature_extractor.h" |
6 | 6 |
7 #include <windows.h> | 7 #include <windows.h> |
8 #include <softpub.h> | 8 #include <softpub.h> |
9 #include <wintrust.h> | 9 #include <wintrust.h> |
10 | 10 |
11 #include "base/files/file_path.h" | 11 #include "base/files/file_path.h" |
12 #include "base/files/memory_mapped_file.h" | 12 #include "base/files/memory_mapped_file.h" |
13 #include "base/logging.h" | 13 #include "base/logging.h" |
14 #include "chrome/common/safe_browsing/csd.pb.h" | 14 #include "chrome/common/safe_browsing/csd.pb.h" |
15 #include "chrome/common/safe_browsing/pe_image_reader_win.h" | 15 #include "chrome/common/safe_browsing/pe_image_reader_win.h" |
16 | 16 |
17 #pragma comment(lib, "wintrust.lib") | 17 #pragma comment(lib, "wintrust.lib") |
18 | 18 |
19 namespace safe_browsing { | 19 namespace safe_browsing { |
20 | 20 |
| 21 namespace { |
| 22 |
| 23 bool ExtractImageHeadersImpl( |
| 24 const base::MemoryMappedFile& file, |
| 25 BinaryFeatureExtractor::ExtractHeadersOption options, |
| 26 ClientDownloadRequest_ImageHeaders* image_headers) { |
| 27 PeImageReader pe_image; |
| 28 if (!pe_image.Initialize(file.data(), file.length())) |
| 29 return false; |
| 30 |
| 31 // Copy the headers. |
| 32 ClientDownloadRequest_PEImageHeaders* pe_headers = |
| 33 image_headers->mutable_pe_headers(); |
| 34 pe_headers->set_dos_header(pe_image.GetDosHeader(), sizeof(IMAGE_DOS_HEADER)); |
| 35 pe_headers->set_file_header(pe_image.GetCoffFileHeader(), |
| 36 sizeof(IMAGE_FILE_HEADER)); |
| 37 size_t optional_header_size = 0; |
| 38 const uint8_t* optional_header_data = |
| 39 pe_image.GetOptionalHeaderData(&optional_header_size); |
| 40 if (pe_image.GetWordSize() == PeImageReader::WORD_SIZE_32) { |
| 41 pe_headers->set_optional_headers32(optional_header_data, |
| 42 optional_header_size); |
| 43 } else { |
| 44 pe_headers->set_optional_headers64(optional_header_data, |
| 45 optional_header_size); |
| 46 } |
| 47 const size_t number_of_sections = pe_image.GetNumberOfSections(); |
| 48 for (size_t i = 0; i != number_of_sections; ++i) { |
| 49 pe_headers->add_section_header(pe_image.GetSectionHeaderAt(i), |
| 50 sizeof(IMAGE_SECTION_HEADER)); |
| 51 } |
| 52 if (!(options & BinaryFeatureExtractor::kOmitExports)) { |
| 53 size_t export_size = 0; |
| 54 const uint8_t* export_section = pe_image.GetExportSection(&export_size); |
| 55 if (export_section) |
| 56 pe_headers->set_export_section_data(export_section, export_size); |
| 57 } |
| 58 size_t number_of_debug_entries = pe_image.GetNumberOfDebugEntries(); |
| 59 for (size_t i = 0; i != number_of_debug_entries; ++i) { |
| 60 const uint8_t* raw_data = NULL; |
| 61 size_t raw_data_size = 0; |
| 62 const IMAGE_DEBUG_DIRECTORY* directory_entry = |
| 63 pe_image.GetDebugEntry(i, &raw_data, &raw_data_size); |
| 64 if (directory_entry) { |
| 65 ClientDownloadRequest_PEImageHeaders_DebugData* debug_data = |
| 66 pe_headers->add_debug_data(); |
| 67 debug_data->set_directory_entry(directory_entry, |
| 68 sizeof(*directory_entry)); |
| 69 if (raw_data) |
| 70 debug_data->set_raw_data(raw_data, raw_data_size); |
| 71 } |
| 72 } |
| 73 |
| 74 return true; |
| 75 } |
| 76 |
| 77 } // namespace |
| 78 |
21 BinaryFeatureExtractor::BinaryFeatureExtractor() {} | 79 BinaryFeatureExtractor::BinaryFeatureExtractor() {} |
22 | 80 |
23 BinaryFeatureExtractor::~BinaryFeatureExtractor() {} | 81 BinaryFeatureExtractor::~BinaryFeatureExtractor() {} |
24 | 82 |
25 void BinaryFeatureExtractor::CheckSignature( | 83 void BinaryFeatureExtractor::CheckSignature( |
26 const base::FilePath& file_path, | 84 const base::FilePath& file_path, |
27 ClientDownloadRequest_SignatureInfo* signature_info) { | 85 ClientDownloadRequest_SignatureInfo* signature_info) { |
28 DVLOG(2) << "Checking signature for " << file_path.value(); | 86 DVLOG(2) << "Checking signature for " << file_path.value(); |
29 | 87 |
30 WINTRUST_FILE_INFO file_info = {0}; | 88 WINTRUST_FILE_INFO file_info = {0}; |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
87 wintrust_data.dwStateAction = WTD_STATEACTION_CLOSE; | 145 wintrust_data.dwStateAction = WTD_STATEACTION_CLOSE; |
88 WinVerifyTrust(static_cast<HWND>(INVALID_HANDLE_VALUE), | 146 WinVerifyTrust(static_cast<HWND>(INVALID_HANDLE_VALUE), |
89 &policy_guid, &wintrust_data); | 147 &policy_guid, &wintrust_data); |
90 } | 148 } |
91 } | 149 } |
92 | 150 |
93 bool BinaryFeatureExtractor::ExtractImageHeaders( | 151 bool BinaryFeatureExtractor::ExtractImageHeaders( |
94 const base::FilePath& file_path, | 152 const base::FilePath& file_path, |
95 ExtractHeadersOption options, | 153 ExtractHeadersOption options, |
96 ClientDownloadRequest_ImageHeaders* image_headers) { | 154 ClientDownloadRequest_ImageHeaders* image_headers) { |
97 // Map the file into memory. | 155 base::MemoryMappedFile mapped_file; |
98 base::MemoryMappedFile file; | 156 if (!mapped_file.Initialize(file_path)) |
99 if (!file.Initialize(file_path)) | |
100 return false; | 157 return false; |
| 158 return ExtractImageHeadersImpl(mapped_file, options, image_headers); |
| 159 } |
101 | 160 |
102 PeImageReader pe_image; | 161 bool BinaryFeatureExtractor::ExtractImageHeadersFromFile( |
103 if (!pe_image.Initialize(file.data(), file.length())) | 162 base::File file, |
| 163 ExtractHeadersOption options, |
| 164 ClientDownloadRequest_ImageHeaders* image_headers) { |
| 165 base::MemoryMappedFile mapped_file; |
| 166 if (!mapped_file.Initialize(file.Pass())) |
104 return false; | 167 return false; |
105 | 168 return ExtractImageHeadersImpl(mapped_file, options, image_headers); |
106 // Copy the headers. | |
107 ClientDownloadRequest_PEImageHeaders* pe_headers = | |
108 image_headers->mutable_pe_headers(); | |
109 pe_headers->set_dos_header(pe_image.GetDosHeader(), sizeof(IMAGE_DOS_HEADER)); | |
110 pe_headers->set_file_header(pe_image.GetCoffFileHeader(), | |
111 sizeof(IMAGE_FILE_HEADER)); | |
112 size_t optional_header_size = 0; | |
113 const uint8_t* optional_header_data = | |
114 pe_image.GetOptionalHeaderData(&optional_header_size); | |
115 if (pe_image.GetWordSize() == PeImageReader::WORD_SIZE_32) { | |
116 pe_headers->set_optional_headers32(optional_header_data, | |
117 optional_header_size); | |
118 } else { | |
119 pe_headers->set_optional_headers64(optional_header_data, | |
120 optional_header_size); | |
121 } | |
122 const size_t number_of_sections = pe_image.GetNumberOfSections(); | |
123 for (size_t i = 0; i != number_of_sections; ++i) { | |
124 pe_headers->add_section_header(pe_image.GetSectionHeaderAt(i), | |
125 sizeof(IMAGE_SECTION_HEADER)); | |
126 } | |
127 if (!(options & kOmitExports)) { | |
128 size_t export_size = 0; | |
129 const uint8_t* export_section = pe_image.GetExportSection(&export_size); | |
130 if (export_section) | |
131 pe_headers->set_export_section_data(export_section, export_size); | |
132 } | |
133 size_t number_of_debug_entries = pe_image.GetNumberOfDebugEntries(); | |
134 for (size_t i = 0; i != number_of_debug_entries; ++i) { | |
135 const uint8_t* raw_data = NULL; | |
136 size_t raw_data_size = 0; | |
137 const IMAGE_DEBUG_DIRECTORY* directory_entry = | |
138 pe_image.GetDebugEntry(i, &raw_data, &raw_data_size); | |
139 if (directory_entry) { | |
140 ClientDownloadRequest_PEImageHeaders_DebugData* debug_data = | |
141 pe_headers->add_debug_data(); | |
142 debug_data->set_directory_entry(directory_entry, | |
143 sizeof(*directory_entry)); | |
144 if (raw_data) | |
145 debug_data->set_raw_data(raw_data, raw_data_size); | |
146 } | |
147 } | |
148 | |
149 return true; | |
150 } | 169 } |
151 | 170 |
152 } // namespace safe_browsing | 171 } // namespace safe_browsing |
OLD | NEW |