1 : // Copyright 2013 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 : // The PECoffRelinker class serves as the base class of both PERelinker and
16 : // CoffRelinker for common implementation routines.
17 :
18 : #ifndef SYZYGY_PE_PE_COFF_RELINKER_H_
19 : #define SYZYGY_PE_PE_COFF_RELINKER_H_
20 :
21 : #include <vector>
22 :
23 : #include "base/files/file_path.h"
24 : #include "syzygy/block_graph/transform_policy.h"
25 : #include "syzygy/pe/image_layout.h"
26 : #include "syzygy/pe/relinker.h"
27 :
28 : namespace pe {
29 :
30 : // Base class for full file-to-file transformations of PE or COFF files;
31 : // PERelinker and CoffRelinker extend this class. It provides implementation
32 : // for common book-keeping routines for transforms and orderers.
33 : class PECoffRelinker : public RelinkerInterface {
34 : public:
35 : typedef block_graph::BlockGraph BlockGraph;
36 : typedef block_graph::BlockGraphOrdererInterface Orderer;
37 : typedef block_graph::BlockGraphTransformInterface BlockGraphTransform;
38 : typedef block_graph::ImageLayoutTransformInterface ImageLayoutTransform;
39 : typedef block_graph::OrderedBlockGraph OrderedBlockGraph;
40 : typedef block_graph::TransformPolicyInterface TransformPolicyInterface;
41 :
42 : // Change the path to the main input file. By default, it is empty.
43 : //
44 : // @param input_path the new input path.
45 E : void set_input_path(const base::FilePath& input_path) {
46 E : input_path_ = input_path;
47 E : }
48 :
49 : // Change the path to the main output file. By default, it is empty.
50 : //
51 : // @param output_path the new output path.
52 E : void set_output_path(const base::FilePath& output_path) {
53 E : output_path_ = output_path;
54 E : }
55 :
56 : // Specify whether to allow output files to be overwritten. By default, it
57 : // is false. If @p allow_overwrite is true, input and output files may
58 : // overlap.
59 : //
60 : // @param allow_overwrite whether the output files may be overwritten.
61 E : void set_allow_overwrite(bool allow_overwrite) {
62 E : allow_overwrite_ = allow_overwrite;
63 E : }
64 :
65 : // @returns the path to the main input file.
66 E : const base::FilePath& input_path() const { return input_path_; }
67 :
68 : // @returns the path to the main output file.
69 E : const base::FilePath& output_path() const { return output_path_; }
70 :
71 : // @returns whether output files may be overwritten.
72 E : bool allow_overwrite() const { return allow_overwrite_; }
73 :
74 : // @see RelinkerInterface::AppendTransform()
75 : virtual bool AppendTransform(BlockGraphTransform* transform) override;
76 :
77 : // @see RelinkerInterface::AppendTransforms()
78 : virtual bool AppendTransforms(
79 : const std::vector<BlockGraphTransform*>& transforms) override;
80 :
81 : // @see RelinkerInterface::AppendOrderer()
82 : virtual bool AppendOrderer(Orderer* orderer) override;
83 :
84 : // @see RelinkerInterface::AppendOrderers()
85 : virtual bool AppendOrderers(const std::vector<Orderer*>& orderers) override;
86 :
87 : // @see RelinkerInterface::AppendLayoutTransform()
88 : virtual bool AppendLayoutTransform(ImageLayoutTransform* transform) override;
89 :
90 : // @see RelinkerInterface::AppendLayoutTransforms()
91 : virtual bool AppendLayoutTransforms(
92 : const std::vector<ImageLayoutTransform*>& transforms) override;
93 :
94 : // The following accessors provide access to properties not initialized by
95 : // this class; they should be valid after the relinker has been
96 : // initialized in some fashion specific to the child class.
97 : // @{
98 : // After initialization, retrieve the original unmodified image layout.
99 : //
100 : // @returns the original image layout.
101 E : const ImageLayout& input_image_layout() const {
102 E : DCHECK(inited_);
103 E : return input_image_layout_;
104 E : }
105 :
106 : // After initialization, retrieve the block graph being processed; the
107 : // returned block graph will reflect changes made by passes.
108 : //
109 : // @returns the block graph.
110 E : const BlockGraph& block_graph() const {
111 E : DCHECK(inited_);
112 E : return block_graph_;
113 E : }
114 :
115 : // After initialization, retrieve the headers block being processed; the
116 : // returned block will reflect changes made by passes.
117 : //
118 : // @returns the headers block.
119 E : const BlockGraph::Block* headers_block() const {
120 E : DCHECK(inited_);
121 E : return headers_block_;
122 E : }
123 : // @}
124 :
125 : protected:
126 : // Construct a default PECoffRelinker. Initialize properties to default
127 : // values.
128 : // @param transform_policy The policy that dictates how to apply transforms.
129 : explicit PECoffRelinker(const TransformPolicyInterface* transform_policy);
130 :
131 : // Apply user-supplied transforms to the block graph
132 : // @returns true on success, or false on failure.
133 : bool ApplyUserTransforms();
134 :
135 : // Apply user-supplied orderers to the specified ordered block graph, or
136 : // the default original orderer if none has been added.
137 : // @param ordered_graph the ordered block graph to order or reorder.
138 : // @returns true on success, or false on failure.
139 : bool ApplyUserOrderers(OrderedBlockGraph* ordered_graph);
140 :
141 : // Apply user supplied transforms to the layout of the PE image
142 : // @returns true on success, or false on failure.
143 : bool ApplyUserLayoutTransforms(pe::ImageLayout* image_layout,
144 : OrderedBlockGraph* ordered_graph);
145 :
146 : // The policy that dictates how to apply transforms.
147 : const TransformPolicyInterface* transform_policy_;
148 :
149 : // The path to the main input file.
150 : base::FilePath input_path_;
151 :
152 : // The path to the main input file.
153 : base::FilePath output_path_;
154 :
155 : // Whether we may overwrite output files.
156 : bool allow_overwrite_;
157 :
158 : // Transforms to be applied, in order.
159 : std::vector<BlockGraphTransform*> transforms_;
160 :
161 : // Orderers to be applied, in order.
162 : std::vector<Orderer*> orderers_;
163 :
164 : // Layout transforms to be applied, in order.
165 : std::vector<ImageLayoutTransform*> layout_transforms_;
166 :
167 : // Whether the relinker has been initialized.
168 : bool inited_;
169 :
170 : // These refer to the original image, and don't change after init.
171 : ImageLayout input_image_layout_;
172 :
173 : // The block graph being processed. May be altered by user-supplied
174 : // passes.
175 : BlockGraph block_graph_;
176 :
177 : // The headers block of block_graph_.
178 : BlockGraph::Block* headers_block_;
179 :
180 : private:
181 : DISALLOW_COPY_AND_ASSIGN(PECoffRelinker);
182 : };
183 :
184 : } // namespace pe
185 :
186 : #endif // SYZYGY_PE_PE_COFF_RELINKER_H_
|