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