1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/common/safe_browsing/binary_feature_extractor.h"
7 #include "chrome/common/safe_browsing/csd.pb.h"
8 #include "chrome/common/safe_browsing/mach_o_image_reader_mac.h"
10 namespace safe_browsing
{
12 bool BinaryFeatureExtractor::ExtractImageFeaturesFromData(
13 const uint8_t* data
, size_t data_size
,
14 ExtractHeadersOption options
,
15 ClientDownloadRequest_ImageHeaders
* image_headers
,
16 google::protobuf::RepeatedPtrField
<std::string
>* signed_data
) {
17 MachOImageReader image_reader
;
18 if (!image_reader
.Initialize(data
, data_size
))
21 // If the image is fat, get all its MachO images. Otherwise, just scan
23 std::vector
<MachOImageReader
*> images
;
24 if (image_reader
.IsFat())
25 images
= image_reader
.GetFatImages();
27 images
.push_back(&image_reader
);
29 for (const auto& mach_o_reader
: images
) {
30 // Record the entire mach_header struct.
31 auto mach_o_headers
= image_headers
->mutable_mach_o_headers()->Add();
32 if (mach_o_reader
->Is64Bit()) {
33 const mach_header_64
* header
= mach_o_reader
->GetMachHeader64();
34 mach_o_headers
->set_mach_header(header
, sizeof(*header
));
36 const mach_header
* header
= mach_o_reader
->GetMachHeader();
37 mach_o_headers
->set_mach_header(header
, sizeof(*header
));
40 // Store the load commands for the Mach-O binary.
41 auto proto_load_commands
= mach_o_headers
->mutable_load_commands();
42 const std::vector
<MachOImageReader::LoadCommand
>& load_commands
=
43 mach_o_reader
->GetLoadCommands();
44 for (const auto& load_command
: load_commands
) {
45 auto proto_load_command
= proto_load_commands
->Add();
46 proto_load_command
->set_command_id(load_command
.cmd());
47 proto_load_command
->set_command(&load_command
.data
[0],
48 load_command
.data
.size());
51 // Get the signature information.
53 std::vector
<uint8_t> code_signature
;
54 if (mach_o_reader
->GetCodeSignatureInfo(&code_signature
)) {
55 signed_data
->Add()->append(
56 reinterpret_cast<const char*>(&code_signature
[0]),
57 code_signature
.size());
65 } // namespace safe_browsing