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 E : BlockGraph* block_graph, BlockGraph::Block* /*dos_header_block*/) {
35 E : DCHECK(block_graph != NULL);
36 :
37 E : metadata_block_ = NULL;
38 :
39 E : pe::PEFile pe_file;
40 E : if (!pe_file.Init(module_path_)) {
41 i : LOG(ERROR) << "Unable to initialize PEFile for module \""
42 : << module_path_.value() << "\".";
43 i : return false;
44 : }
45 :
46 E : pe::PEFile::Signature pe_signature;
47 E : pe_file.GetSignature(&pe_signature);
48 :
49 E : pe::Metadata metadata;
50 E : if (!metadata.Init(pe_signature)) {
51 i : LOG(ERROR) << "Unable to initialize metadata.";
52 i : return false;
53 : }
54 :
55 E : const BlockGraph::Section* section = NULL;
56 E : BlockGraph::Block* block = NULL;
57 :
58 : // Look for the section.
59 : BlockGraph::SectionMap::const_iterator section_it =
60 E : block_graph->sections().begin();
61 E : for (; section_it != block_graph->sections().end(); ++section_it) {
62 E : if (section_it->second.name() == common::kSyzygyMetadataSectionName) {
63 E : section = §ion_it->second;
64 E : break;
65 : }
66 E : }
67 :
68 : // If we found the section then look for the block.
69 E : if (section != NULL) {
70 : BlockGraph::BlockMap::iterator block_it =
71 E : block_graph->blocks_mutable().begin();
72 E : for (; block_it != block_graph->blocks_mutable().end(); ++block_it) {
73 E : if (block_it->second.section() == section->id()) {
74 : // We reuse the first metadata block we find, but we shouldn't find
75 : // any others.
76 E : if (block != NULL) {
77 E : LOG(ERROR) << "Found multiple metadata blocks.";
78 E : return false;
79 : }
80 E : block = &block_it->second;
81 : }
82 E : }
83 : } else {
84 : // Otherwise, create the section.
85 : section = block_graph->AddSection(common::kSyzygyMetadataSectionName,
86 E : kReadOnlyDataCharacteristics);
87 E : DCHECK(section != NULL);
88 : }
89 :
90 : // If no block was found, create one.
91 E : if (block == NULL) {
92 E : block = block_graph->AddBlock(BlockGraph::DATA_BLOCK, 0, "Metadata");
93 E : block->set_section(section->id());
94 : }
95 E : DCHECK(block != NULL);
96 :
97 : // Fill in the metadata block.
98 E : if (!metadata.SaveToBlock(block)) {
99 i : LOG(ERROR) << "Unable to create metadata block.";
100 i : return false;
101 : }
102 :
103 E : metadata_block_ = block;
104 :
105 E : return true;
106 E : }
107 :
108 : } // namespace transforms
109 : } // namespace pe
|