blob: da8d945b69ed7c913604cef50037230fa9c249ba [file] [log] [blame]
// Copyright 2012 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Declares ImageLayout, a lightweight structure that imposes a layout on a
// BlockGraph via an AddressSpace and a set of section headers.
#ifndef SYZYGY_PE_IMAGE_LAYOUT_H_
#define SYZYGY_PE_IMAGE_LAYOUT_H_
#include <windows.h>
#include <winnt.h>
#include <string>
#include <vector>
#include "syzygy/block_graph/block_graph.h"
#include "syzygy/core/address_space.h"
namespace pe {
// An ImageLayout imposes a layout on a BlockGraph via an AddressSpace over the
// blocks and a set of section headers.
struct ImageLayout {
// Per-section information.
struct SectionInfo {
// Name of the section, note that this will be truncated to a max of
// 8 characters on output.
std::string name;
// The section's starting RVA, must be a multiple of the image's
// SectionAlignment value.
core::RelativeAddress addr;
// The virtual size of the section, must be greater than zero. Any
// part of the section that extends beyond data_size is implicitly
// zero initialized.
size_t size;
// The initialized data size of the section, must be a multiple of the
// image's FileAlignment value.
size_t data_size;
// The section characteristics, a bitmask of IMAGE_SCN_* values.
uint32_t characteristics;
};
// Creates an empty image layout on the supplied block graph.
explicit ImageLayout(block_graph::BlockGraph* block_graph);
// The sections in the image.
std::vector<SectionInfo> sections;
// The blocks that should be written to the image.
block_graph::BlockGraph::AddressSpace blocks;
};
// Copies section headers to section info.
// @param num_sections the number of sections to copy.
// @param section_headers the array of section headers.
// @param sections the vector of section info structs to fill out.
void CopySectionHeadersToImageLayout(
size_t num_sections,
const IMAGE_SECTION_HEADER* section_headers,
std::vector<ImageLayout::SectionInfo>* sections);
// Copies section headers to section info.
// @param nt_headers_block the block containing the NT headers.
// @param layout the image layout to be populated.
bool CopyHeaderToImageLayout(
const block_graph::BlockGraph::Block* nt_headers_block,
ImageLayout* layout);
// For testing.
inline bool operator==(const ImageLayout::SectionInfo& a,
const ImageLayout::SectionInfo& b) {
return a.name == b.name && a.addr == b.addr &&
a.size == b.size && a.data_size == b.data_size &&
a.characteristics == b.characteristics;
}
// Generates a canonical ImageLayout. If the contained BlockGraph is unmodified
// as output by Decomposer, this will be the same as the original ImageLayout,
// up to but not including the SectionInfo.data_size values: we are more
// aggressive at trimming empty data from the end of a section. This does not
// modify the underlying BlockGraph.
//
// @param image_layout the ImageLayout to populate.
// @returns true on success, false otherwise.
// @pre The AddressSpace contained by image_layout is empty.
bool BuildCanonicalImageLayout(ImageLayout* image_layout);
// Given an @p input_image_layout generate a second @p output_image_layout that
// is identical to the first but not containing any padding blocks. This also
// removes the corresponding padding blocks from the underlying block-graph.
// @note The @p input_image_layout is invalid after this operation as it
// will contain dangling block pointers.
// @param input_image_layout The input image layout to be copied.
// @param output_image_layout The image layout to receive the new layout minus
// padding blocks. This must be initially empty and over the same
// block-graph as @p input_image_layout.
bool CopyImageLayoutWithoutPadding(const ImageLayout& input_image_layout,
ImageLayout* output_image_layout);
} // namespace pe
#endif // SYZYGY_PE_IMAGE_LAYOUT_H_