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