OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/zip_analyzer.h" | 5 #include "chrome/common/safe_browsing/zip_analyzer.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 #include <stdint.h> | 8 #include <stdint.h> |
9 | 9 |
10 #include <memory> | 10 #include <memory> |
11 #include <set> | 11 #include <set> |
12 | 12 |
| 13 #if defined(OS_MACOSX) |
| 14 #include <mach-o/fat.h> |
| 15 #include <mach-o/loader.h> |
| 16 #endif // OS_MACOSX |
| 17 |
13 #include "base/i18n/streaming_utf8_validator.h" | 18 #include "base/i18n/streaming_utf8_validator.h" |
14 #include "base/logging.h" | 19 #include "base/logging.h" |
15 #include "base/macros.h" | 20 #include "base/macros.h" |
| 21 #include "build/build_config.h" |
16 #include "chrome/common/safe_browsing/archive_analyzer_results.h" | 22 #include "chrome/common/safe_browsing/archive_analyzer_results.h" |
17 #include "chrome/common/safe_browsing/binary_feature_extractor.h" | 23 #include "chrome/common/safe_browsing/binary_feature_extractor.h" |
18 #include "chrome/common/safe_browsing/download_protection_util.h" | 24 #include "chrome/common/safe_browsing/download_protection_util.h" |
19 #include "chrome/common/safe_browsing/file_type_policies.h" | 25 #include "chrome/common/safe_browsing/file_type_policies.h" |
20 #include "components/safe_browsing/csd.pb.h" | 26 #include "components/safe_browsing/csd.pb.h" |
21 #include "crypto/secure_hash.h" | 27 #include "crypto/secure_hash.h" |
22 #include "crypto/sha2.h" | 28 #include "crypto/sha2.h" |
23 #include "third_party/zlib/google/zip_reader.h" | 29 #include "third_party/zlib/google/zip_reader.h" |
24 | 30 |
25 namespace safe_browsing { | 31 namespace safe_browsing { |
(...skipping 27 matching lines...) Expand all Loading... |
53 if (!zip::FileWriterDelegate::WriteBytes(data, num_bytes)) | 59 if (!zip::FileWriterDelegate::WriteBytes(data, num_bytes)) |
54 return false; | 60 return false; |
55 sha256_->Update(data, num_bytes); | 61 sha256_->Update(data, num_bytes); |
56 return true; | 62 return true; |
57 } | 63 } |
58 | 64 |
59 void HashingFileWriter::ComputeDigest(uint8_t* digest, size_t digest_length) { | 65 void HashingFileWriter::ComputeDigest(uint8_t* digest, size_t digest_length) { |
60 sha256_->Finish(digest, digest_length); | 66 sha256_->Finish(digest, digest_length); |
61 } | 67 } |
62 | 68 |
| 69 #if defined(OS_MACOSX) |
| 70 bool StringIsMachOMagic(std::string bytes) { |
| 71 if (bytes.length() < sizeof(uint32_t)) |
| 72 return false; |
| 73 |
| 74 uint32_t magic; |
| 75 memcpy(&magic, bytes.c_str(), sizeof(uint32_t)); |
| 76 |
| 77 return magic == FAT_MAGIC || magic == FAT_CIGAM || magic == MH_MAGIC || |
| 78 magic == MH_CIGAM || magic == MH_MAGIC_64 || magic == MH_CIGAM_64; |
| 79 } |
| 80 #endif // OS_MACOSX |
| 81 |
63 void AnalyzeContainedFile( | 82 void AnalyzeContainedFile( |
64 const scoped_refptr<BinaryFeatureExtractor>& binary_feature_extractor, | 83 const scoped_refptr<BinaryFeatureExtractor>& binary_feature_extractor, |
65 const base::FilePath& file_path, | 84 const base::FilePath& file_path, |
66 zip::ZipReader* reader, | 85 zip::ZipReader* reader, |
67 base::File* temp_file, | 86 base::File* temp_file, |
68 ClientDownloadRequest::ArchivedBinary* archived_binary) { | 87 ClientDownloadRequest::ArchivedBinary* archived_binary) { |
69 std::string file_basename(file_path.BaseName().AsUTF8Unsafe()); | 88 std::string file_basename(file_path.BaseName().AsUTF8Unsafe()); |
70 if (base::StreamingUtf8Validator::Validate(file_basename)) | 89 if (base::StreamingUtf8Validator::Validate(file_basename)) |
71 archived_binary->set_file_basename(file_basename); | 90 archived_binary->set_file_basename(file_basename); |
72 archived_binary->set_download_type( | 91 archived_binary->set_download_type( |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
109 bool advanced = true; | 128 bool advanced = true; |
110 for (; reader.HasMore(); advanced = reader.AdvanceToNextEntry()) { | 129 for (; reader.HasMore(); advanced = reader.AdvanceToNextEntry()) { |
111 if (!advanced) { | 130 if (!advanced) { |
112 DVLOG(1) << "Could not advance to next entry, aborting zip scan."; | 131 DVLOG(1) << "Could not advance to next entry, aborting zip scan."; |
113 return; | 132 return; |
114 } | 133 } |
115 if (!reader.OpenCurrentEntryInZip()) { | 134 if (!reader.OpenCurrentEntryInZip()) { |
116 DVLOG(1) << "Failed to open current entry in zip file"; | 135 DVLOG(1) << "Failed to open current entry in zip file"; |
117 continue; | 136 continue; |
118 } | 137 } |
| 138 |
119 const base::FilePath& file = reader.current_entry_info()->file_path(); | 139 const base::FilePath& file = reader.current_entry_info()->file_path(); |
| 140 bool current_entry_is_executable; |
| 141 #if defined(OS_MACOSX) |
| 142 std::string magic; |
| 143 reader.ExtractPartOfCurrentEntryToString(sizeof(uint32_t), &magic); |
| 144 current_entry_is_executable = |
| 145 FileTypePolicies::GetInstance()->IsCheckedBinaryFile(file) || |
| 146 StringIsMachOMagic(magic); |
| 147 #else |
| 148 current_entry_is_executable = |
| 149 FileTypePolicies::GetInstance()->IsCheckedBinaryFile(file); |
| 150 #endif // OS_MACOSX |
| 151 |
120 if (FileTypePolicies::GetInstance()->IsArchiveFile(file)) { | 152 if (FileTypePolicies::GetInstance()->IsArchiveFile(file)) { |
121 DVLOG(2) << "Downloaded a zipped archive: " << file.value(); | 153 DVLOG(2) << "Downloaded a zipped archive: " << file.value(); |
122 results->has_archive = true; | 154 results->has_archive = true; |
123 archived_archive_filenames.insert(file.BaseName()); | 155 archived_archive_filenames.insert(file.BaseName()); |
124 ClientDownloadRequest::ArchivedBinary* archived_archive = | 156 ClientDownloadRequest::ArchivedBinary* archived_archive = |
125 results->archived_binary.Add(); | 157 results->archived_binary.Add(); |
126 std::string file_basename_utf8(file.BaseName().AsUTF8Unsafe()); | 158 std::string file_basename_utf8(file.BaseName().AsUTF8Unsafe()); |
127 if (base::StreamingUtf8Validator::Validate(file_basename_utf8)) | 159 if (base::StreamingUtf8Validator::Validate(file_basename_utf8)) |
128 archived_archive->set_file_basename(file_basename_utf8); | 160 archived_archive->set_file_basename(file_basename_utf8); |
129 archived_archive->set_download_type( | 161 archived_archive->set_download_type( |
130 ClientDownloadRequest::ZIPPED_ARCHIVE); | 162 ClientDownloadRequest::ZIPPED_ARCHIVE); |
131 } else if (FileTypePolicies::GetInstance()->IsCheckedBinaryFile(file)) { | 163 } else if (current_entry_is_executable) { |
132 DVLOG(2) << "Downloaded a zipped executable: " << file.value(); | 164 #if defined(OS_MACOSX) |
133 results->has_executable = true; | 165 // This check prevents running analysis on .app files since they are |
134 AnalyzeContainedFile(binary_feature_extractor, file, &reader, &temp_file, | 166 // really just directories and will cause binary feature extraction |
135 results->archived_binary.Add()); | 167 // to fail. |
| 168 if (file.Extension().compare(".app") == 0) { |
| 169 DVLOG(2) << "Downloaded a zipped .app directory: " << file.value(); |
| 170 } else { |
| 171 #endif // OS_MACOSX |
| 172 DVLOG(2) << "Downloaded a zipped executable: " << file.value(); |
| 173 results->has_executable = true; |
| 174 LOG(ERROR) << "just set it to true"; |
| 175 AnalyzeContainedFile(binary_feature_extractor, file, &reader, |
| 176 &temp_file, results->archived_binary.Add()); |
| 177 #if defined(OS_MACOSX) |
| 178 } |
| 179 #endif // OS_MACOSX |
136 } else { | 180 } else { |
137 DVLOG(3) << "Ignoring non-binary file: " << file.value(); | 181 DVLOG(3) << "Ignoring non-binary file: " << file.value(); |
138 } | 182 } |
139 } | 183 } |
140 results->archived_archive_filenames.assign(archived_archive_filenames.begin(), | 184 results->archived_archive_filenames.assign(archived_archive_filenames.begin(), |
141 archived_archive_filenames.end()); | 185 archived_archive_filenames.end()); |
142 results->success = true; | 186 results->success = true; |
143 } | 187 } |
144 | 188 |
145 } // namespace zip_analyzer | 189 } // namespace zip_analyzer |
146 } // namespace safe_browsing | 190 } // namespace safe_browsing |
OLD | NEW |