1 : // Copyright 2014 Google Inc. All Rights Reserved.
2 : //
3 : // Licensed under the Apache License, Version 2.0 (the "License");
4 : // you may not use this file except in compliance with the License.
5 : // You may obtain a copy of the License at
6 : //
7 : // http://www.apache.org/licenses/LICENSE-2.0
8 : //
9 : // Unless required by applicable law or agreed to in writing, software
10 : // distributed under the License is distributed on an "AS IS" BASIS,
11 : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 : // See the License for the specific language governing permissions and
13 : // limitations under the License.
14 :
15 : #include "syzygy/zap_timestamp/zap_timestamp_app.h"
16 :
17 : #include "base/strings/string_number_conversions.h"
18 :
19 : namespace zap_timestamp {
20 :
21 : namespace {
22 :
23 : const char kUsageFormatStr[] =
24 : "Usage: %ls --input-image=<PE file>\n"
25 : "\n"
26 : " A tool that normalizes the GUID and timestamps associated with a\n"
27 : " given PE/PDB file pair. The PDB files matching each given PE file can\n"
28 : " be tracked down automatically.\n"
29 : "\n"
30 : "Options:\n"
31 : " --input-pdb=<PDB path>\n"
32 : " If specified then this PDB will be used as the matching PDB. Will\n"
33 : " fail if the PDB and the PE file are not paired.\n"
34 : " --no-write-image\n"
35 : " If this is specified then the PE file will not be written.\n"
36 : " --no-write-pdb\n"
37 : " If this is specified then the PDB file will not be written. Has no\n"
38 : " effect for a PE file with no paired PDB.\n"
39 : " --output-image=<PE path>\n"
40 : " Specifies the output image path. If not specified defaults to\n"
41 : " writing the image in place.\n"
42 : " --output-pdb=<PDB path>\n"
43 : " Specifies the output PDB path. If this is not specified but\n"
44 : " --output-image is, then will place the PDB alongside the output\n"
45 : " image with the same basename. If this is specified then\n"
46 : " --output-image must also be specified."
47 : " --overwrite\n"
48 : " If specified will allow overwriting of existing output files. Must\n"
49 : " be specified for in place processing.\n"
50 : " --timestamp-value=<seconds since Jan 1, 1970>\n"
51 : " The timestamp value to use in the binaries, if not specified an\n"
52 : " arbitrary date in the past will be used (default to Jan 1, 2010).\n";
53 :
54 : void PrintUsage(FILE* out,
55 : const base::FilePath& program,
56 E : const base::StringPiece& message) {
57 E : if (!message.empty()) {
58 E : ::fwrite(message.data(), 1, message.length(), out);
59 E : ::fprintf(out, "\n\n");
60 : }
61 :
62 E : ::fprintf(out, kUsageFormatStr, program.BaseName().value().c_str());
63 E : }
64 :
65 : } // namespace
66 :
67 E : bool ZapTimestampApp::ParseCommandLine(const base::CommandLine* command_line) {
68 E : DCHECK(command_line != NULL);
69 :
70 E : if (command_line->HasSwitch("help")) {
71 E : PrintUsage(out(), command_line->GetProgram(), nullptr);
72 E : return false;
73 : }
74 :
75 E : base::FilePath path = command_line->GetSwitchValuePath("input-image");
76 E : if (path.empty()) {
77 : PrintUsage(out(), command_line->GetProgram(),
78 E : "You must specify --input-image.");
79 E : return false;
80 : }
81 E : zap_.set_input_image(path);
82 :
83 E : zap_.set_input_pdb(command_line->GetSwitchValuePath("input-pdb"));
84 E : zap_.set_output_image(command_line->GetSwitchValuePath("output-image"));
85 E : zap_.set_output_pdb(command_line->GetSwitchValuePath("output-pdb"));
86 E : zap_.set_write_image(!command_line->HasSwitch("no-write-image"));
87 E : zap_.set_write_pdb(!command_line->HasSwitch("no-write-pdb"));
88 E : zap_.set_overwrite(command_line->HasSwitch("overwrite"));
89 :
90 E : if (command_line->HasSwitch("timestamp-value")) {
91 E : size_t timestamp_value = 0;
92 : if (!base::StringToSizeT(
93 : command_line->GetSwitchValueASCII("timestamp-value"),
94 E : ×tamp_value)) {
95 i : LOG(ERROR) << "Unable to read the timestamp value from the command line.";
96 i : return false;
97 : }
98 E : zap_.set_timestamp_value(timestamp_value);
99 : }
100 :
101 E : return true;
102 E : }
103 :
104 : int ZapTimestampApp::Run() {
105 : if (!zap_.Init())
106 : return 1;
107 :
108 : if (!zap_.Zap())
109 : return 1;
110 :
111 : return 0;
112 : }
113 :
114 : } // namespace zap_timestamp
|