blob: 38757e45b1a2deb30eeb657776fa3a7eb346d6c4 [file] [log] [blame] [edit]
// 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.
#ifndef SYZYGY_PE_PE_UTILS_H_
#define SYZYGY_PE_PE_UTILS_H_
#include <windows.h>
#include <winnt.h>
#include "syzygy/block_graph/block_graph.h"
namespace pe {
// Typical section names.
extern const char kCodeSectionName[];
extern const char kReadOnlyDataSectionName[];
extern const char kReadWriteDataSectionName[];
extern const char kRelocSectionName[];
extern const char kResourceSectionName[];
extern const char kTlsSectionName[];
// Typical section characteristics.
extern const DWORD kCodeCharacteristics;
extern const DWORD kReadOnlyDataCharacteristics;
extern const DWORD kReadWriteDataCharacteristics;
extern const DWORD kRelocCharacteristics;
// Validates @p dos_header_block for the the size, magic constants and
// other properties of a valid DOS header.
// @returns true iff @p dos_header_block has all the correct properties
// of a DOS header.
bool IsValidDosHeaderBlock(
const block_graph::BlockGraph::Block* dos_header_block);
// Validates @p nt_headers_block for the the size, magic constants and
// other properties of valid NT headers.
// @returns true iff block has correct size and signature for a DOS
// header block.
bool IsValidNtHeadersBlock(
const block_graph::BlockGraph::Block* nt_headers_block);
// Retrieves and validates the NT headers block from a valid DOS headers block.
// @returns the NT headers block, iff it can be retrieved from the DOS headers
// block, and if the NT headers block has valid signatures.
const block_graph::BlockGraph::Block* GetNtHeadersBlockFromDosHeaderBlock(
const block_graph::BlockGraph::Block* dos_header_block);
block_graph::BlockGraph::Block* GetNtHeadersBlockFromDosHeaderBlock(
block_graph::BlockGraph::Block* dos_header_block);
// Updates the provided DOS header block in preparation for writing a module
// from a BlockGraph. Trims any superfluous data and inserts a new DOS stub.
// After this has been applied IsValidDosHeaderBlock will succeed.
// @param dos_header_block the DOS header block to update.
// @returns true on success, false otherwise.
bool UpdateDosHeader(block_graph::BlockGraph::Block* dos_header_block);
typedef std::pair<block_graph::BlockGraph::Block*,
block_graph::BlockGraph::Offset> EntryPoint;
typedef std::set<EntryPoint> EntryPointSet;
// Retrieves the image entry point into @p entry_points IFF the image is an
// EXE. If the image is not an EXE then this is a NOP.
// @param dos_header_block the DOS header block of the image.
// @param entry_points the entry-point will be inserted into this set if the
// image in question is an executable.
// @returns true on success, false otherwise. It is not considered a failure
// if @p entry_points is left unchanged because @p dos_header_block
// indicates that the image is not an executable.
// @note The returned @p entry_point will have a call-signature taking no
// arguments.
bool GetExeEntryPoint(block_graph::BlockGraph::Block* dos_header_block,
EntryPoint* entry_point);
// Retrieves the image entry point into @p entry_points IFF the image is a
// DLL. If the image is not a DLL, or if the DLL has no entry point, then this
// is a NOP.
// @param dos_header_block the DOS header block of the image.
// @param entry_points the entry-point will be inserted into this set if the
// image in question is a DLL. Note that the entry-point for a DLL is
// optional; if the DLL has no entry point, the Block* of the returned
// EntryPoint structure will be NULL.
// @returns true on success, false otherwise. It is not considered a failure
// if @p entry_points is left unchanged because @p dos_header_block
// indicates that the image is not a DLL.
// @note The returned @p entry_point, if any, will have a call-signature
// matching that of DllMain.
bool GetDllEntryPoint(block_graph::BlockGraph::Block* dos_header_block,
EntryPoint* entry_point);
// Retrieves the TLS initializer entry-points into @p entry_points.
// @param dos_header_block the DOS header block of the image.
// @param entry_points the entry-point will be inserted into this set if the
// image in question is a DLL. If the set already contains elements it will
// be added to.
// @returns true on success, false otherwise.
// @note The returned @p entry_points, if any, will have a call-signature
// matching that of DllMain.
// TODO(rogerm): We may want to change this to output to an EntryPointVector
// instead of to a set. This would be more consistent with the actual
// representation of the TLS initializers. That said, our actual usage of
// the returned entry-points would require us to eliminate duplicates after
// the fact. Left as a set for now, under suspicion of YAGNI.
bool GetTlsInitializers(block_graph::BlockGraph::Block* dos_header_block,
EntryPointSet* entry_points);
// Check if an image contains an import entry.
// @param The image's header-block.
// @param dll_name The name of the DLL.
// @param contains_dependence Boolean to indicate if the image contains the
// import entry.
// @returns true in case of success, false otherwise.
bool HasImportEntry(block_graph::BlockGraph::Block* header_block,
const base::StringPiece& dll_name,
bool* has_import_entry);
} // namespace pe
#endif // SYZYGY_PE_PE_UTILS_H_