blob: 225fc258cefa4f76881901360e681462e8a4680c [file] [log] [blame]
huangsf953e4072017-07-28 01:16:211// Copyright 2017 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.
4
Samuel Huang577ef6c2018-03-13 18:19:345#include "components/zucchini/zucchini_commands.h"
huangsf953e4072017-07-28 01:16:216
Samuel Huange8d07b752017-08-21 16:05:257#include <stddef.h>
8#include <stdint.h>
9
huangs252600a2017-07-31 22:19:4810#include <ostream>
Samuel Huang73a64ff2018-04-30 22:47:5211#include <string>
Samuel Huang577ef6c2018-03-13 18:19:3412#include <utility>
huangs252600a2017-07-31 22:19:4813
14#include "base/command_line.h"
15#include "base/files/file.h"
16#include "base/files/file_path.h"
17#include "base/files/memory_mapped_file.h"
huangsf953e4072017-07-28 01:16:2118#include "base/logging.h"
Samuel Huang577ef6c2018-03-13 18:19:3419#include "components/zucchini/buffer_view.h"
20#include "components/zucchini/crc32.h"
21#include "components/zucchini/io_utils.h"
22#include "components/zucchini/mapped_file.h"
23#include "components/zucchini/patch_writer.h"
24#include "components/zucchini/zucchini_integration.h"
25#include "components/zucchini/zucchini_tools.h"
huangsf953e4072017-07-28 01:16:2126
27namespace {
28
Etienne Pierre-Doray73ed4232017-08-10 01:28:4129/******** Command-line Switches ********/
30
Samuel Huangd943db62017-08-23 21:46:5731constexpr char kSwitchDump[] = "dump";
Samuel Huang73a64ff2018-04-30 22:47:5232constexpr char kSwitchImpose[] = "impose";
Samuel Huang21879c32018-03-21 18:54:0333constexpr char kSwitchKeep[] = "keep";
Samuel Huangd943db62017-08-23 21:46:5734constexpr char kSwitchRaw[] = "raw";
Etienne Pierre-Doray73ed4232017-08-10 01:28:4135
huangsf953e4072017-07-28 01:16:2136} // namespace
37
huangs252600a2017-07-31 22:19:4838zucchini::status::Code MainGen(MainParams params) {
39 CHECK_EQ(3U, params.file_paths.size());
Samuel Huang9f0f3252018-06-21 15:50:2240 return zucchini::Generate(
41 params.file_paths[0], params.file_paths[1], params.file_paths[2],
42 params.command_line.HasSwitch(kSwitchKeep),
43 params.command_line.HasSwitch(kSwitchRaw),
44 params.command_line.GetSwitchValueASCII(kSwitchImpose));
huangsf953e4072017-07-28 01:16:2145}
46
huangs252600a2017-07-31 22:19:4847zucchini::status::Code MainApply(MainParams params) {
48 CHECK_EQ(3U, params.file_paths.size());
Etienne Pierre-Doray455d1ae2017-08-24 01:17:5449 return zucchini::Apply(params.file_paths[0], params.file_paths[1],
Samuel Huang21879c32018-03-21 18:54:0350 params.file_paths[2],
51 params.command_line.HasSwitch(kSwitchKeep));
Samuel Huangd943db62017-08-23 21:46:5752}
53
Etienne Pierre-doray559d77a2021-10-28 21:16:0454zucchini::status::Code MainVerify(MainParams params) {
55 CHECK_EQ(1U, params.file_paths.size());
56 return zucchini::VerifyPatch(params.file_paths[0]);
57}
58
Samuel Huangd943db62017-08-23 21:46:5759zucchini::status::Code MainRead(MainParams params) {
60 CHECK_EQ(1U, params.file_paths.size());
Calder Kitagawa796f2fb2018-02-12 17:14:4961 base::File input_file(params.file_paths[0],
Greg Thompsonf176eba32020-07-18 01:29:3962 base::File::FLAG_OPEN | base::File::FLAG_READ |
Alexei Svitkine9f7f7c8f2021-11-16 22:01:3263 base::File::FLAG_WIN_SHARE_DELETE);
Calder Kitagawaab7fbfb2018-02-09 18:06:0264 zucchini::MappedFileReader input(std::move(input_file));
65 if (input.HasError()) {
66 LOG(ERROR) << "Error with file " << params.file_paths[0].value() << ": "
67 << input.error();
Samuel Huangd943db62017-08-23 21:46:5768 return zucchini::status::kStatusFileReadError;
Calder Kitagawaab7fbfb2018-02-09 18:06:0269 }
Samuel Huangd943db62017-08-23 21:46:5770
71 bool do_dump = params.command_line.HasSwitch(kSwitchDump);
72 zucchini::status::Code status = zucchini::ReadReferences(
73 {input.data(), input.length()}, do_dump, params.out);
74 if (status != zucchini::status::kStatusSuccess)
75 params.err << "Fatal error found when dumping references." << std::endl;
76 return status;
huangs252600a2017-07-31 22:19:4877}
78
Samuel Huangdd90d832017-11-03 18:14:0279zucchini::status::Code MainDetect(MainParams params) {
80 CHECK_EQ(1U, params.file_paths.size());
Calder Kitagawa796f2fb2018-02-12 17:14:4981 base::File input_file(params.file_paths[0],
Greg Thompsonf176eba32020-07-18 01:29:3982 base::File::FLAG_OPEN | base::File::FLAG_READ |
Alexei Svitkine9f7f7c8f2021-11-16 22:01:3283 base::File::FLAG_WIN_SHARE_DELETE);
Calder Kitagawaab7fbfb2018-02-09 18:06:0284 zucchini::MappedFileReader input(std::move(input_file));
85 if (input.HasError()) {
86 LOG(ERROR) << "Error with file " << params.file_paths[0].value() << ": "
87 << input.error();
Samuel Huangdd90d832017-11-03 18:14:0288 return zucchini::status::kStatusFileReadError;
Calder Kitagawaab7fbfb2018-02-09 18:06:0289 }
Samuel Huangdd90d832017-11-03 18:14:0290
91 std::vector<zucchini::ConstBufferView> sub_image_list;
92 zucchini::status::Code result = zucchini::DetectAll(
93 {input.data(), input.length()}, params.out, &sub_image_list);
94 if (result != zucchini::status::kStatusSuccess)
95 params.err << "Fatal error found when detecting executables." << std::endl;
96 return result;
97}
98
Samuel Huangfdb2f3a2017-12-20 17:45:1499zucchini::status::Code MainMatch(MainParams params) {
100 CHECK_EQ(2U, params.file_paths.size());
Calder Kitagawaab7fbfb2018-02-09 18:06:02101 using base::File;
Greg Thompsonf176eba32020-07-18 01:29:39102 File old_file(params.file_paths[0], File::FLAG_OPEN | File::FLAG_READ |
Alexei Svitkine9f7f7c8f2021-11-16 22:01:32103 base::File::FLAG_WIN_SHARE_DELETE);
Calder Kitagawaab7fbfb2018-02-09 18:06:02104 zucchini::MappedFileReader old_image(std::move(old_file));
105 if (old_image.HasError()) {
106 LOG(ERROR) << "Error with file " << params.file_paths[0].value() << ": "
107 << old_image.error();
Samuel Huangfdb2f3a2017-12-20 17:45:14108 return zucchini::status::kStatusFileReadError;
Calder Kitagawaab7fbfb2018-02-09 18:06:02109 }
Greg Thompsonf176eba32020-07-18 01:29:39110 File new_file(params.file_paths[1], File::FLAG_OPEN | File::FLAG_READ |
Alexei Svitkine9f7f7c8f2021-11-16 22:01:32111 base::File::FLAG_WIN_SHARE_DELETE);
Calder Kitagawaab7fbfb2018-02-09 18:06:02112 zucchini::MappedFileReader new_image(std::move(new_file));
Calder Kitagawa3135d7d12018-03-14 19:28:36113 if (new_image.HasError()) {
Calder Kitagawaab7fbfb2018-02-09 18:06:02114 LOG(ERROR) << "Error with file " << params.file_paths[1].value() << ": "
115 << new_image.error();
Samuel Huangfdb2f3a2017-12-20 17:45:14116 return zucchini::status::kStatusFileReadError;
Calder Kitagawaab7fbfb2018-02-09 18:06:02117 }
Samuel Huang73a64ff2018-04-30 22:47:52118
119 std::string imposed_matches =
120 params.command_line.GetSwitchValueASCII(kSwitchImpose);
Samuel Huangfdb2f3a2017-12-20 17:45:14121 zucchini::status::Code status =
122 zucchini::MatchAll({old_image.data(), old_image.length()},
Samuel Huang73a64ff2018-04-30 22:47:52123 {new_image.data(), new_image.length()},
124 std::move(imposed_matches), params.out);
Samuel Huangfdb2f3a2017-12-20 17:45:14125 if (status != zucchini::status::kStatusSuccess)
126 params.err << "Fatal error found when matching executables." << std::endl;
127 return status;
128}
129
huangs252600a2017-07-31 22:19:48130zucchini::status::Code MainCrc32(MainParams params) {
131 CHECK_EQ(1U, params.file_paths.size());
Calder Kitagawa796f2fb2018-02-12 17:14:49132 base::File image_file(params.file_paths[0],
Greg Thompsonf176eba32020-07-18 01:29:39133 base::File::FLAG_OPEN | base::File::FLAG_READ |
Alexei Svitkine9f7f7c8f2021-11-16 22:01:32134 base::File::FLAG_WIN_SHARE_DELETE);
Calder Kitagawaab7fbfb2018-02-09 18:06:02135 zucchini::MappedFileReader image(std::move(image_file));
136 if (image.HasError()) {
137 LOG(ERROR) << "Error with file " << params.file_paths[0].value() << ": "
138 << image.error();
huangs252600a2017-07-31 22:19:48139 return zucchini::status::kStatusFileReadError;
Calder Kitagawaab7fbfb2018-02-09 18:06:02140 }
huangs252600a2017-07-31 22:19:48141
142 uint32_t crc =
143 zucchini::CalculateCrc32(image.data(), image.data() + image.length());
144 params.out << "CRC32: " << zucchini::AsHex<8>(crc) << std::endl;
huangsf953e4072017-07-28 01:16:21145 return zucchini::status::kStatusSuccess;
146}