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 : #ifndef SYZYGY_PE_PE_UTILS_H_
16 : #define SYZYGY_PE_PE_UTILS_H_
17 :
18 : #include <windows.h>
19 : #include <winnt.h>
20 :
21 : #include "syzygy/block_graph/block_graph.h"
22 :
23 m : namespace pe {
24 :
25 : // @name Operations on PE/COFF headers.
26 : // @{
27 : // Known section types.
28 m : enum SectionType {
29 m : kSectionCode,
30 m : kSectionData,
31 m : kSectionUnknown
32 m : };
33 :
34 : // Typical section names.
35 m : extern const char kCodeSectionName[];
36 m : extern const char kReadOnlyDataSectionName[];
37 m : extern const char kReadWriteDataSectionName[];
38 m : extern const char kRelocSectionName[];
39 m : extern const char kResourceSectionName[];
40 m : extern const char kTlsSectionName[];
41 :
42 : // Typical section characteristics.
43 m : extern const DWORD kCodeCharacteristics;
44 m : extern const DWORD kReadOnlyDataCharacteristics;
45 m : extern const DWORD kReadWriteDataCharacteristics;
46 m : extern const DWORD kRelocCharacteristics;
47 :
48 : // Validates @p dos_header_block for the size, magic constants and other
49 : // properties of a valid DOS header.
50 : // @returns true iff @p dos_header_block has all the correct properties
51 : // of a DOS header.
52 m : bool IsValidDosHeaderBlock(
53 m : const block_graph::BlockGraph::Block* dos_header_block);
54 :
55 : // Validates @p nt_headers_block for the the size, magic constants and
56 : // other properties of valid NT headers.
57 : // @returns true iff block has correct size and signature for a DOS
58 : // header block.
59 m : bool IsValidNtHeadersBlock(
60 m : const block_graph::BlockGraph::Block* nt_headers_block);
61 :
62 : // Retrieves and validates the NT headers block from a valid DOS headers block.
63 : // @returns the NT headers block, iff it can be retrieved from the DOS headers
64 : // block, and if the NT headers block has valid signatures.
65 m : const block_graph::BlockGraph::Block* GetNtHeadersBlockFromDosHeaderBlock(
66 m : const block_graph::BlockGraph::Block* dos_header_block);
67 m : block_graph::BlockGraph::Block* GetNtHeadersBlockFromDosHeaderBlock(
68 m : block_graph::BlockGraph::Block* dos_header_block);
69 :
70 : // Updates the provided DOS header block in preparation for writing a module
71 : // from a BlockGraph. Trims any superfluous data and inserts a new DOS stub.
72 : // After this has been applied IsValidDosHeaderBlock will succeed.
73 : // @param dos_header_block the DOS header block to update.
74 : // @returns true on success, false otherwise.
75 m : bool UpdateDosHeader(block_graph::BlockGraph::Block* dos_header_block);
76 :
77 : // Determine the type of a section based on its attributes. Used to tag
78 : // blocks with an appropriate type.
79 : //
80 : // @param header the header of the section.
81 : // @returns the type of section.
82 m : SectionType GetSectionType(const IMAGE_SECTION_HEADER& header);
83 : // @}
84 :
85 : // @name Block graph helpers.
86 : // @{
87 : // The separator that is used between the multiple symbol names that can be
88 : // associated with a single label.
89 m : extern const char kLabelNameSep[];
90 :
91 : // Add the specified label to @p block, merging with existing labels at the
92 : // same position, if any. Label names are joined with kLabelNameSep.
93 : // Attributes are OR-ed.
94 : //
95 : // @param offset the position to insert the label at.
96 : // @param name the name of the label to insert.
97 : // @param label_attributes attributes to add to the label.
98 : // @param block the block to add the label to.
99 : // @returns true on success, false on failure.
100 m : bool AddLabelToBlock(block_graph::BlockGraph::Offset offset,
101 m : const base::StringPiece& name,
102 m : block_graph::BlockGraph::LabelAttributes label_attributes,
103 m : block_graph::BlockGraph::Block* block);
104 :
105 : // Create sections in @p image corresponding to the ones in @p image_file,
106 : // copying over relevant information.
107 : //
108 : // @tparam ImageFile the class of the file reader; must be derived
109 : // from PECoffFile.
110 : // @param image_file the image file to read sections from.
111 : // @param block_graph the block graph to add sections to.
112 : // @returns true on success, false on failure.
113 m : template <typename ImageFile>
114 m : bool CopySectionInfoToBlockGraph(const ImageFile& image_file,
115 m : block_graph::BlockGraph* block_graph);
116 : // @}
117 :
118 : // @name Operations on entry points.
119 : // @{
120 m : typedef std::pair<block_graph::BlockGraph::Block*,
121 m : block_graph::BlockGraph::Offset> EntryPoint;
122 m : typedef std::set<EntryPoint> EntryPointSet;
123 :
124 : // Retrieves the image entry point into @p entry_points IFF the image is an
125 : // EXE. If the image is not an EXE then this is a NOP.
126 : // @param dos_header_block the DOS header block of the image.
127 : // @param entry_points the entry-point will be inserted into this set if the
128 : // image in question is an executable.
129 : // @returns true on success, false otherwise. It is not considered a failure
130 : // if @p entry_points is left unchanged because @p dos_header_block
131 : // indicates that the image is not an executable.
132 : // @note The returned @p entry_point will have a call-signature taking no
133 : // arguments.
134 m : bool GetExeEntryPoint(block_graph::BlockGraph::Block* dos_header_block,
135 m : EntryPoint* entry_point);
136 :
137 : // Retrieves the image entry point into @p entry_points IFF the image is a
138 : // DLL. If the image is not a DLL, or if the DLL has no entry point, then this
139 : // is a NOP.
140 : // @param dos_header_block the DOS header block of the image.
141 : // @param entry_points the entry-point will be inserted into this set if the
142 : // image in question is a DLL. Note that the entry-point for a DLL is
143 : // optional; if the DLL has no entry point, the Block* of the returned
144 : // EntryPoint structure will be NULL.
145 : // @returns true on success, false otherwise. It is not considered a failure
146 : // if @p entry_points is left unchanged because @p dos_header_block
147 : // indicates that the image is not a DLL.
148 : // @note The returned @p entry_point, if any, will have a call-signature
149 : // matching that of DllMain.
150 m : bool GetDllEntryPoint(block_graph::BlockGraph::Block* dos_header_block,
151 m : EntryPoint* entry_point);
152 :
153 : // Retrieves the TLS initializer entry-points into @p entry_points.
154 : // @param dos_header_block the DOS header block of the image.
155 : // @param entry_points the entry-point will be inserted into this set if the
156 : // image in question is a DLL. If the set already contains elements it will
157 : // be added to.
158 : // @returns true on success, false otherwise.
159 : // @note The returned @p entry_points, if any, will have a call-signature
160 : // matching that of DllMain.
161 : // TODO(rogerm): We may want to change this to output to an EntryPointVector
162 : // instead of to a set. This would be more consistent with the actual
163 : // representation of the TLS initializers. That said, our actual usage of
164 : // the returned entry-points would require us to eliminate duplicates after
165 : // the fact. Left as a set for now, under suspicion of YAGNI.
166 m : bool GetTlsInitializers(block_graph::BlockGraph::Block* dos_header_block,
167 m : EntryPointSet* entry_points);
168 :
169 : // Check if an image contains an import entry.
170 : // @param The image's header-block.
171 : // @param dll_name The name of the DLL.
172 : // @param contains_dependence Boolean to indicate if the image contains the
173 : // import entry.
174 : // @returns true in case of success, false otherwise.
175 m : bool HasImportEntry(block_graph::BlockGraph::Block* header_block,
176 m : const base::StringPiece& dll_name,
177 m : bool* has_import_entry);
178 : // @}
179 :
180 : // Types used by the redirection primitive.
181 m : typedef std::pair<block_graph::BlockGraph::Block*,
182 m : block_graph::BlockGraph::Offset> ReferenceDest;
183 m : typedef std::map<ReferenceDest, ReferenceDest> ReferenceMap;
184 :
185 : // Redirect references in a block-graph, except for references originating from
186 : // PE structures. Any non-PE-structure block in src_blocks will have its
187 : // references examined. Any reference found as a key in @p redirects will be
188 : // remapped to its corresponding value.
189 : // @param src The original referred destination that is to be redirected.
190 : // @param dst The redirected destination to be referred to.
191 : // @param redirects A map of original to redirected destinations.
192 m : void RedirectReferences(const ReferenceMap& redirects);
193 :
194 m : } // namespace pe
195 :
196 : #include "syzygy/pe/pe_utils_impl.h"
197 :
198 : #endif // SYZYGY_PE_PE_UTILS_H_
|