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 ImageLayout, a lightweight structure that imposes a layout on a
16 : // BlockGraph via an AddressSpace and a set of section headers.
17 :
18 : #ifndef SYZYGY_PE_IMAGE_LAYOUT_H_
19 : #define SYZYGY_PE_IMAGE_LAYOUT_H_
20 :
21 : #include <windows.h>
22 : #include <winnt.h>
23 : #include <string>
24 : #include <vector>
25 :
26 : #include "syzygy/block_graph/block_graph.h"
27 : #include "syzygy/core/address_space.h"
28 :
29 : namespace pe {
30 :
31 : // An ImageLayout imposes a layout on a BlockGraph via an AddressSpace over the
32 : // blocks and a set of section headers.
33 : struct ImageLayout {
34 : // Per-section information.
35 : struct SectionInfo {
36 : // Name of the section, note that this will be truncated to a max of
37 : // 8 characters on output.
38 : std::string name;
39 : // The section's starting RVA, must be a multiple of the image's
40 : // SectionAlignment value.
41 : core::RelativeAddress addr;
42 : // The virtual size of the section, must be greater than zero. Any
43 : // part of the section that extends beyond data_size is implicitly
44 : // zero initialized.
45 : size_t size;
46 : // The initialized data size of the section, must be a multiple of the
47 : // image's FileAlignment value.
48 : size_t data_size;
49 : // The section characteristics, a bitmask of IMAGE_SCN_* values.
50 : uint32_t characteristics;
51 : };
52 :
53 : // Creates an empty image layout on the supplied block graph.
54 : explicit ImageLayout(block_graph::BlockGraph* block_graph);
55 :
56 : // The sections in the image.
57 : std::vector<SectionInfo> sections;
58 :
59 : // The blocks that should be written to the image.
60 : block_graph::BlockGraph::AddressSpace blocks;
61 : };
62 :
63 : // Copies section headers to section info.
64 : // @param num_sections the number of sections to copy.
65 : // @param section_headers the array of section headers.
66 : // @param sections the vector of section info structs to fill out.
67 : void CopySectionHeadersToImageLayout(
68 : size_t num_sections,
69 : const IMAGE_SECTION_HEADER* section_headers,
70 : std::vector<ImageLayout::SectionInfo>* sections);
71 :
72 : // Copies section headers to section info.
73 : // @param nt_headers_block the block containing the NT headers.
74 : // @param layout the image layout to be populated.
75 : bool CopyHeaderToImageLayout(
76 : const block_graph::BlockGraph::Block* nt_headers_block,
77 : ImageLayout* layout);
78 :
79 : // For testing.
80 : inline bool operator==(const ImageLayout::SectionInfo& a,
81 E : const ImageLayout::SectionInfo& b) {
82 E : return a.name == b.name && a.addr == b.addr &&
83 : a.size == b.size && a.data_size == b.data_size &&
84 : a.characteristics == b.characteristics;
85 E : }
86 :
87 : // Generates a canonical ImageLayout. If the contained BlockGraph is unmodified
88 : // as output by Decomposer, this will be the same as the original ImageLayout,
89 : // up to but not including the SectionInfo.data_size values: we are more
90 : // aggressive at trimming empty data from the end of a section. This does not
91 : // modify the underlying BlockGraph.
92 : //
93 : // @param image_layout the ImageLayout to populate.
94 : // @returns true on success, false otherwise.
95 : // @pre The AddressSpace contained by image_layout is empty.
96 : bool BuildCanonicalImageLayout(ImageLayout* image_layout);
97 :
98 : // Given an @p input_image_layout generate a second @p output_image_layout that
99 : // is identical to the first but not containing any padding blocks. This also
100 : // removes the corresponding padding blocks from the underlying block-graph.
101 : // @note The @p input_image_layout is invalid after this operation as it
102 : // will contain dangling block pointers.
103 : // @param input_image_layout The input image layout to be copied.
104 : // @param output_image_layout The image layout to receive the new layout minus
105 : // padding blocks. This must be initially empty and over the same
106 : // block-graph as @p input_image_layout.
107 : bool CopyImageLayoutWithoutPadding(const ImageLayout& input_image_layout,
108 : ImageLayout* output_image_layout);
109 :
110 : } // namespace pe
111 :
112 : #endif // SYZYGY_PE_IMAGE_LAYOUT_H_
|