1 : // Copyright 2012 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 : // Declares a class that allows for the normalization of a PE file and its
16 : // corresponding PDB file.
17 :
18 : #ifndef SYZYGY_ZAP_TIMESTAMP_ZAP_TIMESTAMP_H_
19 : #define SYZYGY_ZAP_TIMESTAMP_ZAP_TIMESTAMP_H_
20 :
21 : #include "base/files/file_path.h"
22 : #include "base/strings/string_piece.h"
23 : #include "syzygy/block_graph/block_graph.h"
24 : #include "syzygy/core/address_space.h"
25 : #include "syzygy/pdb/pdb_file.h"
26 : #include "syzygy/pe/image_layout.h"
27 : #include "syzygy/pe/pe_file.h"
28 :
29 : namespace zap_timestamp {
30 :
31 : // Utility class for normalizing a PE file and the matching PDB file. They vary
32 : // largely in terms of timestamps and hash values, hence the name of the class.
33 : class ZapTimestamp {
34 : public:
35 : ZapTimestamp();
36 :
37 : // @name Mutators.
38 : // @{
39 E : void set_input_image(const base::FilePath& input_image) {
40 E : input_image_ = input_image;
41 E : }
42 E : void set_input_pdb(const base::FilePath& input_pdb) {
43 E : input_pdb_ = input_pdb;
44 E : }
45 E : void set_output_image(const base::FilePath& output_image) {
46 E : output_image_ = output_image;
47 E : }
48 E : void set_output_pdb(const base::FilePath& output_pdb) {
49 E : output_pdb_ = output_pdb;
50 E : }
51 E : void set_write_image(bool write_image) {
52 E : write_image_ = write_image;
53 E : }
54 E : void set_write_pdb(bool write_pdb) {
55 E : write_pdb_ = write_pdb;
56 E : }
57 E : void set_overwrite(bool overwrite) {
58 E : overwrite_ = overwrite;
59 E : }
60 E : void set_timestamp_value(size_t timestamp_value) {
61 E : timestamp_data_ = static_cast<size_t>(timestamp_value);
62 E : }
63 : // @}
64 :
65 : // @name Accessors.
66 : // @{
67 E : const base::FilePath& input_image() const { return input_image_; }
68 E : const base::FilePath& input_pdb() const { return input_pdb_; }
69 E : const base::FilePath& output_image() const { return output_image_; }
70 E : const base::FilePath& output_pdb() const { return output_pdb_; }
71 E : bool write_image() const { return write_image_; }
72 E : bool write_pdb() const { return write_pdb_; }
73 E : bool overwrite() const { return overwrite_; }
74 E : size_t timestamp_value() const {
75 E : return static_cast<size_t>(timestamp_data_);
76 E : }
77 : // @}
78 :
79 : // Prepares for modifying the given PE file. Tracks down all of the bytes
80 : // to be modified and prepares the new values to be stored. Searches for the
81 : // matching PDB file and does the same thing with it.
82 : // @returns true on success, false otherwise.
83 : bool Init();
84 :
85 : // Modifies the given PE file (and its associated PDB file, if applicable).
86 : // Output will be written to |output_image| and |output_pdb|. If these are
87 : // not specified the transform will be applied in place.
88 : // @returns true on success, false on failure.
89 : // @pre Init has been successfully called.
90 : bool Zap();
91 :
92 : // Forward declarations. These are public so they can be used by anonymous
93 : // helper functions in zap_timestamp.cc.
94 : struct PatchData;
95 : typedef core::AddressSpace<core::FileOffsetAddress, size_t, PatchData>
96 : PatchAddressSpace;
97 :
98 : private:
99 : // Ensures the PE file exists and is valid, and searches for the corresponding
100 : // PDB file. After this runs both input_image_ and input_pdb_ are initialized
101 : // and point to valid corresponding files.
102 : bool ValidatePeAndPdbFiles();
103 :
104 : // Infers and validates output paths. After this |output_image_| and
105 : // |output_pdb_| are configured.
106 : bool ValidateOutputPaths();
107 :
108 : // Decomposes the PE file. After this is complete block_graph_, image_layout_
109 : // and pe_file_ and dos_header_block_ have been initialized.
110 : bool DecomposePeFile();
111 :
112 : // Paints the regions of the PE file that need to be modified.
113 : bool MarkPeFileRanges();
114 :
115 : // Calculates a PDB GUID using the non-changing parts of the PE file.
116 : bool CalculatePdbGuid();
117 :
118 : // Loads the PDB file and updates its in-memory representation.
119 : bool LoadAndUpdatePdbFile();
120 :
121 : // @{
122 : // These do the actual writing of the individual files.
123 : bool WritePeFile();
124 : bool WritePdbFile();
125 : // @}
126 :
127 : // Initialized by DecomposePeFile.
128 : block_graph::BlockGraph block_graph_;
129 : pe::ImageLayout image_layout_;
130 : pe::PEFile pe_file_;
131 : block_graph::BlockGraph::Block* dos_header_block_;
132 :
133 : // Populated by MarkPeFileRanges.
134 : PatchAddressSpace pe_file_addr_space_;
135 :
136 : // Populated by LoadPdbFile and modified by UpdatePdbFile.
137 : scoped_ptr<pdb::PdbFile> pdb_file_;
138 :
139 : // These house the new values to be written when the image is zapped.
140 : DWORD timestamp_data_;
141 : DWORD pdb_age_data_;
142 : GUID pdb_guid_data_;
143 :
144 : // Controls the transform. Configured externally.
145 : base::FilePath input_image_;
146 : base::FilePath input_pdb_;
147 : base::FilePath output_image_;
148 : base::FilePath output_pdb_;
149 : bool write_image_;
150 : bool write_pdb_;
151 : bool overwrite_;
152 :
153 : DISALLOW_COPY_AND_ASSIGN(ZapTimestamp);
154 : };
155 :
156 : // Used to keep track of data in the image that is to be changed, and the
157 : // new values to be written.
158 : struct ZapTimestamp::PatchData {
159 E : PatchData(const uint8* data, const base::StringPiece& name)
160 : : data(data) {
161 E : name.CopyToString(&this->name);
162 E : }
163 : const uint8* data;
164 : std::string name;
165 : };
166 :
167 : } // namespace zap_timestamp
168 :
169 : #endif // SYZYGY_ZAP_TIMESTAMP_ZAP_TIMESTAMP_H_
|