blob: 6b2cf7d099401be9fddef814e81feb15aa3ad202 [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.
//
// Defines a PE-specific block-graph transform that finds or adds imports to a
// given module. Multiple libraries may be specified, and multiple functions per
// library. If an import is not found and the mode is kFindOnly, then the
// import will be added. This may also cause an entire imported module to
// be added.
//
// Use is as follows:
//
// ImportedModule foo_dll("foo.dll");
// size_t foo_foo_index = foo_dll.AddSymbol("foo");
// size_t foo_bar_index = foo_dll.AddSymbol("bar");
//
// PEAddImportsTransform add_imports_transform;
// add_imports_transform.AddModule(&foo_dll);
// add_imports_transform.TransformBlockGraph(block_graph, dos_header_block);
//
// // Create a reference to function 'bar' in 'foo.dll'.
// BlockGraph::Reference foo_bar_ref;
// CHECK(foo_dll.GetSymbolReference(foo_bar_index, &foo_bar_ref));
// some_block->SetReference(some_offset, foo_bar_ref);
//
// NOTE: The references provided by GetSymbolReference are only valid
// immediately after they are constructed. If the import directory entries
// are changed between creating the reference and adding it to a block,
// than it may have been invalidated.
#ifndef SYZYGY_PE_TRANSFORMS_PE_ADD_IMPORTS_TRANSFORM_H_
#define SYZYGY_PE_TRANSFORMS_PE_ADD_IMPORTS_TRANSFORM_H_
#include <windows.h>
#include "syzygy/block_graph/typed_block.h"
#include "syzygy/block_graph/transforms/named_transform.h"
#include "syzygy/pe/transforms/pe_coff_add_imports_transform.h"
namespace pe {
namespace transforms {
using block_graph::transforms::NamedBlockGraphTransformImpl;
// A transform for adding imported modules/symbols to a given block-graph.
class PEAddImportsTransform
: public NamedBlockGraphTransformImpl<PEAddImportsTransform>,
public PECoffAddImportsTransform {
public:
typedef block_graph::BlockGraph BlockGraph;
typedef block_graph::TransformPolicyInterface TransformPolicyInterface;
PEAddImportsTransform();
// Performs the transform. Adds entries for any missing modules and
// symbols, returning references to their entries via the ImportedModule
// objects.
//
// If a date/time stamp is specified in an imported module, it will be
// used to update the import descriptor binding field (which indicates
// which version of the library is currently bound in the import table);
// this can be used to provide stubs at program launch time, that will be
// replaced by the loader once the real library is loaded.
//
// @param policy The policy object restricting how the transform is applied.
// @param block_graph the BlockGraph to populate.
// @param dos_header_block the block containing the module's DOS header.
// @returns true on success, false otherwise.
virtual bool TransformBlockGraph(
const TransformPolicyInterface* policy,
BlockGraph* block_graph,
BlockGraph::Block* dos_header_block) OVERRIDE;
// @returns a pointer to the Block containing the Image Import Descriptor.
BlockGraph::Block* image_import_descriptor_block() {
return image_import_descriptor_block_;
}
// @returns a pointer to the Block containing the Import Address Table.
BlockGraph::Block* import_address_table_block() {
return import_address_table_block_;
}
// The name of this transform.
static const char kTransformName[];
protected:
// Processes normal imports. If |find_only| is false then this will add the
// appropriate PE structures and inject missing imports.
bool FindOrAddImports(bool find_only,
BlockGraph* block_graph,
BlockGraph::Block* nt_headers_block);
// Processes delay-load imports. This only searches for existing ones, and
// currently does not add any new delay-load imports or related PE structures.
bool FindDelayLoadImports(BlockGraph* block_graph,
BlockGraph::Block* nt_headers_block);
// We cache various blocks for easier unittesting.
BlockGraph::Block* image_import_descriptor_block_;
BlockGraph::Block* import_address_table_block_;
BlockGraph::Block* image_delayload_descriptor_block_;
};
} // namespace transforms
} // namespace pe
#endif // SYZYGY_PE_TRANSFORMS_PE_ADD_IMPORTS_TRANSFORM_H_