| Index: chrome/common/safe_browsing/zip_analyzer.cc
|
| diff --git a/chrome/common/safe_browsing/zip_analyzer.cc b/chrome/common/safe_browsing/zip_analyzer.cc
|
| index d2ce62513eb8039a1c50e91d8a2faff4eb3176ce..6f1d5e261fc663c387f8e7f229efd6ef3bc107ad 100644
|
| --- a/chrome/common/safe_browsing/zip_analyzer.cc
|
| +++ b/chrome/common/safe_browsing/zip_analyzer.cc
|
| @@ -5,13 +5,85 @@
|
| #include "chrome/common/safe_browsing/zip_analyzer.h"
|
|
|
| #include "base/logging.h"
|
| +#include "base/macros.h"
|
| +#include "chrome/common/safe_browsing/binary_feature_extractor.h"
|
| +#include "chrome/common/safe_browsing/csd.pb.h"
|
| #include "chrome/common/safe_browsing/download_protection_util.h"
|
| +#include "chrome/common/safe_browsing/zip_analyzer_results.h"
|
| +#include "crypto/secure_hash.h"
|
| +#include "crypto/sha2.h"
|
| #include "third_party/zlib/google/zip_reader.h"
|
|
|
| namespace safe_browsing {
|
| namespace zip_analyzer {
|
|
|
| -void AnalyzeZipFile(base::File zip_file, Results* results) {
|
| +namespace {
|
| +
|
| +// A writer delegate that computes a SHA-256 hash digest over the data while
|
| +// writing it to a file.
|
| +class HashingFileWriter : public zip::FileWriterDelegate {
|
| + public:
|
| + explicit HashingFileWriter(base::File* file);
|
| +
|
| + // zip::FileWriterDelegate methods:
|
| + bool WriteBytes(const char* data, int num_bytes) override;
|
| +
|
| + void ComputeDigest(uint8_t* digest, size_t digest_length);
|
| +
|
| + private:
|
| + scoped_ptr<crypto::SecureHash> sha256_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(HashingFileWriter);
|
| +};
|
| +
|
| +HashingFileWriter::HashingFileWriter(base::File* file)
|
| + : zip::FileWriterDelegate(file),
|
| + sha256_(crypto::SecureHash::Create(crypto::SecureHash::SHA256)) {
|
| +}
|
| +
|
| +bool HashingFileWriter::WriteBytes(const char* data, int num_bytes) {
|
| + if (!zip::FileWriterDelegate::WriteBytes(data, num_bytes))
|
| + return false;
|
| + sha256_->Update(data, num_bytes);
|
| + return true;
|
| +}
|
| +
|
| +void HashingFileWriter::ComputeDigest(uint8_t* digest, size_t digest_length) {
|
| + sha256_->Finish(digest, digest_length);
|
| +}
|
| +
|
| +void AnalyzeContainedFile(
|
| + const scoped_refptr<BinaryFeatureExtractor>& binary_feature_extractor,
|
| + const base::FilePath& file_path,
|
| + zip::ZipReader* reader,
|
| + base::File* temp_file,
|
| + ClientDownloadRequest_ArchivedBinary* archived_binary) {
|
| + archived_binary->set_file_basename(file_path.BaseName().AsUTF8Unsafe());
|
| + archived_binary->set_download_type(
|
| + download_protection_util::GetDownloadType(file_path));
|
| + archived_binary->set_length(reader->current_entry_info()->original_size());
|
| + HashingFileWriter writer(temp_file);
|
| + if (reader->ExtractCurrentEntry(&writer)) {
|
| + uint8_t digest[crypto::kSHA256Length];
|
| + writer.ComputeDigest(&digest[0], arraysize(digest));
|
| + archived_binary->mutable_digests()->set_sha256(&digest[0],
|
| + arraysize(digest));
|
| + if (!binary_feature_extractor->ExtractImageHeadersFromFile(
|
| + temp_file->Duplicate(),
|
| + BinaryFeatureExtractor::kDefaultOptions,
|
| + archived_binary->mutable_image_headers())) {
|
| + archived_binary->clear_image_headers();
|
| + }
|
| + }
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| +void AnalyzeZipFile(base::File zip_file,
|
| + base::File temp_file,
|
| + Results* results) {
|
| + scoped_refptr<BinaryFeatureExtractor> binary_feature_extractor(
|
| + new BinaryFeatureExtractor());
|
| zip::ZipReader reader;
|
| if (!reader.OpenFromPlatformFile(zip_file.GetPlatformFile())) {
|
| DVLOG(1) << "Failed to open zip file";
|
| @@ -37,7 +109,8 @@ void AnalyzeZipFile(base::File zip_file, Results* results) {
|
| } else {
|
| DVLOG(2) << "Downloaded a zipped executable: " << file.value();
|
| results->has_executable = true;
|
| - break;
|
| + AnalyzeContainedFile(binary_feature_extractor, file, &reader,
|
| + &temp_file, results->archived_binary.Add());
|
| }
|
| } else {
|
| DVLOG(3) << "Ignoring non-binary file: " << file.value();
|
|
|