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 : #include "syzygy/pe/transforms/add_metadata_transform.h"
16 :
17 : #include "syzygy/block_graph/typed_block.h"
18 : #include "syzygy/common/defs.h"
19 : #include "syzygy/pe/metadata.h"
20 : #include "syzygy/pe/pe_file.h"
21 : #include "syzygy/pe/pe_utils.h"
22 :
23 : namespace pe {
24 : namespace transforms {
25 :
26 : const char AddMetadataTransform::kTransformName[] =
27 : "AddMetadataTransform";
28 :
29 : AddMetadataTransform::AddMetadataTransform(const base::FilePath& module_path)
30 E : : module_path_(module_path) {
31 E : }
32 :
33 : bool AddMetadataTransform::TransformBlockGraph(
34 : const TransformPolicyInterface* policy,
35 : BlockGraph* block_graph,
36 E : BlockGraph::Block* /*dos_header_block*/) {
37 E : DCHECK(policy != NULL);
38 E : DCHECK(block_graph != NULL);
39 :
40 E : metadata_block_ = NULL;
41 :
42 E : pe::PEFile pe_file;
43 E : if (!pe_file.Init(module_path_)) {
44 i : LOG(ERROR) << "Unable to initialize PEFile for module \""
45 : << module_path_.value() << "\".";
46 i : return false;
47 : }
48 :
49 E : pe::PEFile::Signature pe_signature;
50 E : pe_file.GetSignature(&pe_signature);
51 :
52 E : pe::Metadata metadata;
53 E : if (!metadata.Init(pe_signature)) {
54 i : LOG(ERROR) << "Unable to initialize metadata.";
55 i : return false;
56 : }
57 :
58 E : const BlockGraph::Section* section = NULL;
59 E : BlockGraph::Block* block = NULL;
60 :
61 : // Look for the section.
62 E : section = block_graph->FindSection(common::kSyzygyMetadataSectionName);
63 :
64 : // If we found the section then look for the block.
65 E : if (section != NULL) {
66 : BlockGraph::BlockMap::iterator block_it =
67 E : block_graph->blocks_mutable().begin();
68 E : for (; block_it != block_graph->blocks_mutable().end(); ++block_it) {
69 E : if (block_it->second.section() == section->id()) {
70 : // We reuse the first metadata block we find, but we shouldn't find
71 : // any others.
72 E : if (block != NULL) {
73 E : LOG(ERROR) << "Found multiple metadata blocks.";
74 E : return false;
75 : }
76 E : block = &block_it->second;
77 : }
78 E : }
79 : } else {
80 : // Otherwise, create the section.
81 : section = block_graph->AddSection(common::kSyzygyMetadataSectionName,
82 E : kReadOnlyDataCharacteristics);
83 E : DCHECK(section != NULL);
84 : }
85 :
86 : // If no block was found, create one.
87 E : if (block == NULL) {
88 E : block = block_graph->AddBlock(BlockGraph::DATA_BLOCK, 0, "Metadata");
89 E : block->set_section(section->id());
90 : }
91 E : DCHECK(block != NULL);
92 :
93 : // Fill in the metadata block.
94 E : if (!metadata.SaveToBlock(block)) {
95 i : LOG(ERROR) << "Unable to create metadata block.";
96 i : return false;
97 : }
98 :
99 E : metadata_block_ = block;
100 :
101 E : return true;
102 E : }
103 :
104 : } // namespace transforms
105 : } // namespace pe
|