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 : // Defines a PE-specific block-graph transform that finds or adds imports to a
16 : // given module. Multiple libraries may be specified, and multiple functions per
17 : // library. If an import is not found and the mode is kFindOnly, then the
18 : // import will be added. This may also cause an entire imported module to
19 : // be added.
20 : //
21 : // Use is as follows:
22 : //
23 : // ImportedModule foo_dll("foo.dll");
24 : // size_t foo_foo_index = foo_dll.AddSymbol("foo");
25 : // size_t foo_bar_index = foo_dll.AddSymbol("bar");
26 : //
27 : // PEAddImportsTransform add_imports_transform;
28 : // add_imports_transform.AddModule(&foo_dll);
29 : // add_imports_transform.TransformBlockGraph(block_graph, dos_header_block);
30 : //
31 : // // Create a reference to function 'bar' in 'foo.dll'.
32 : // BlockGraph::Reference foo_bar_ref;
33 : // CHECK(foo_dll.GetSymbolReference(foo_bar_index, &foo_bar_ref));
34 : // some_block->SetReference(some_offset, foo_bar_ref);
35 : //
36 : // NOTE: The references provided by GetSymbolReference are only valid
37 : // immediately after they are constructed. If the import directory entries
38 : // are changed between creating the reference and adding it to a block,
39 : // than it may have been invalidated.
40 :
41 : #ifndef SYZYGY_PE_TRANSFORMS_PE_ADD_IMPORTS_TRANSFORM_H_
42 : #define SYZYGY_PE_TRANSFORMS_PE_ADD_IMPORTS_TRANSFORM_H_
43 :
44 : #include <windows.h>
45 :
46 : #include "syzygy/block_graph/typed_block.h"
47 : #include "syzygy/block_graph/transforms/named_transform.h"
48 : #include "syzygy/pe/transforms/pe_coff_add_imports_transform.h"
49 :
50 m : namespace pe {
51 m : namespace transforms {
52 :
53 m : using block_graph::transforms::NamedBlockGraphTransformImpl;
54 :
55 : // A transform for adding imported modules/symbols to a given block-graph.
56 m : class PEAddImportsTransform
57 m : : public NamedBlockGraphTransformImpl<PEAddImportsTransform>,
58 m : public PECoffAddImportsTransform {
59 m : public:
60 m : typedef block_graph::BlockGraph BlockGraph;
61 m : typedef block_graph::TransformPolicyInterface TransformPolicyInterface;
62 :
63 m : PEAddImportsTransform();
64 :
65 : // Performs the transform. Adds entries for any missing modules and
66 : // symbols, returning references to their entries via the ImportedModule
67 : // objects.
68 : //
69 : // If a date/time stamp is specified in an imported module, it will be
70 : // used to update the import descriptor binding field (which indicates
71 : // which version of the library is currently bound in the import table);
72 : // this can be used to provide stubs at program launch time, that will be
73 : // replaced by the loader once the real library is loaded.
74 : //
75 : // @param policy The policy object restricting how the transform is applied.
76 : // @param block_graph the BlockGraph to populate.
77 : // @param dos_header_block the block containing the module's DOS header.
78 : // @returns true on success, false otherwise.
79 m : virtual bool TransformBlockGraph(
80 m : const TransformPolicyInterface* policy,
81 m : BlockGraph* block_graph,
82 m : BlockGraph::Block* dos_header_block) override;
83 :
84 : // @returns a pointer to the Block containing the Image Import Descriptor.
85 m : BlockGraph::Block* image_import_descriptor_block() {
86 m : return image_import_descriptor_block_;
87 m : }
88 :
89 : // @returns a pointer to the Block containing the Import Address Table.
90 m : BlockGraph::Block* import_address_table_block() {
91 m : return import_address_table_block_;
92 m : }
93 :
94 : // The name of this transform.
95 m : static const char kTransformName[];
96 :
97 m : protected:
98 : // Processes normal imports. If |find_only| is false then this will add the
99 : // appropriate PE structures and inject missing imports.
100 m : bool FindOrAddImports(bool find_only,
101 m : BlockGraph* block_graph,
102 m : BlockGraph::Block* nt_headers_block);
103 : // Processes delay-load imports. This only searches for existing ones, and
104 : // currently does not add any new delay-load imports or related PE structures.
105 m : bool FindDelayLoadImports(BlockGraph* block_graph,
106 m : BlockGraph::Block* nt_headers_block);
107 :
108 : // We cache various blocks for easier unittesting.
109 m : BlockGraph::Block* image_import_descriptor_block_;
110 m : BlockGraph::Block* import_address_table_block_;
111 m : BlockGraph::Block* image_delayload_descriptor_block_;
112 m : };
113 :
114 m : } // namespace transforms
115 m : } // namespace pe
116 :
117 : #endif // SYZYGY_PE_TRANSFORMS_PE_ADD_IMPORTS_TRANSFORM_H_
|