Index: syzygy/pe/pe_relinker.cc |
diff --git a/syzygy/pe/pe_relinker.cc b/syzygy/pe/pe_relinker.cc |
index 157246cb524899ac1e9dc083091a2725ac02ad89..82b6668eff39e4626b6fdb644321ccca581c3e81 100644 |
--- a/syzygy/pe/pe_relinker.cc |
+++ b/syzygy/pe/pe_relinker.cc |
@@ -1,245 +1,245 @@ |
-// 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. |
- |
-#include "syzygy/pe/pe_relinker.h" |
- |
-#include "base/files/file_util.h" |
-#include "syzygy/pdb/pdb_byte_stream.h" |
-#include "syzygy/pdb/pdb_file.h" |
-#include "syzygy/pdb/pdb_reader.h" |
-#include "syzygy/pdb/pdb_util.h" |
-#include "syzygy/pdb/pdb_writer.h" |
-#include "syzygy/pe/decomposer.h" |
-#include "syzygy/pe/metadata.h" |
-#include "syzygy/pe/pdb_info.h" |
-#include "syzygy/pe/pe_file_writer.h" |
-#include "syzygy/pe/pe_relinker_util.h" |
-#include "syzygy/pe/serialization.h" |
- |
-namespace pe { |
- |
-namespace { |
- |
-typedef block_graph::BlockGraphTransformInterface Transform; |
-typedef block_graph::BlockGraphOrdererInterface Orderer; |
- |
-using block_graph::ApplyBlockGraphTransform; |
-using block_graph::BlockGraph; |
-using block_graph::OrderedBlockGraph; |
-using core::RelativeAddress; |
-using pdb::NameStreamMap; |
-using pdb::PdbByteStream; |
-using pdb::PdbFile; |
-using pdb::PdbInfoHeader70; |
-using pdb::PdbMutatorInterface; |
-using pdb::PdbStream; |
-using pdb::WritablePdbStream; |
- |
-// Decomposes the module enclosed by the given PE file. |
-bool Decompose(const PEFile& pe_file, |
- const base::FilePath& pdb_path, |
- ImageLayout* image_layout, |
- BlockGraph::Block** dos_header_block) { |
- DCHECK(image_layout != NULL); |
- DCHECK(dos_header_block != NULL); |
- |
- LOG(INFO) << "Decomposing module: " << pe_file.path().value(); |
- |
- BlockGraph* block_graph = image_layout->blocks.graph(); |
- ImageLayout orig_image_layout(block_graph); |
- |
- // Decompose the input image. |
- Decomposer decomposer(pe_file); |
- decomposer.set_pdb_path(pdb_path); |
- if (!decomposer.Decompose(&orig_image_layout)) { |
- LOG(ERROR) << "Unable to decompose module: " << pe_file.path().value(); |
- return false; |
- } |
- |
- // Make a copy of the image layout without padding. We don't want to carry |
- // the padding through the toolchain. |
- LOG(INFO) << "Removing padding blocks."; |
- if (!pe::CopyImageLayoutWithoutPadding(orig_image_layout, image_layout)) { |
- LOG(ERROR) << "Failed to remove padding blocks."; |
- return false; |
- } |
- |
- // Get the DOS header block. |
- *dos_header_block = |
- image_layout->blocks.GetBlockByAddress( |
- BlockGraph::RelativeAddress(0)); |
- if (*dos_header_block == NULL) { |
- LOG(ERROR) << "Unable to find the DOS header block."; |
- return false; |
- } |
- |
- return true; |
-} |
- |
-// Writes the image. |
-bool WriteImage(const ImageLayout& image_layout, |
- const base::FilePath& output_path) { |
- PEFileWriter writer(image_layout); |
- |
- LOG(INFO) << "Writing image: " << output_path.value(); |
- if (!writer.WriteImage(output_path)) { |
- LOG(ERROR) << "Failed to write image \"" << output_path.value() << "\"."; |
- return false; |
- } |
- |
- return true; |
-} |
- |
-} // namespace |
- |
-PERelinker::PERelinker(const PETransformPolicy* pe_transform_policy) |
- : PECoffRelinker(pe_transform_policy), |
- pe_transform_policy_(pe_transform_policy), |
- add_metadata_(true), augment_pdb_(true), |
- compress_pdb_(false), strip_strings_(false), |
- padding_(0), code_alignment_(1), output_guid_(GUID_NULL) { |
- DCHECK(pe_transform_policy != NULL); |
-} |
- |
-bool PERelinker::AppendPdbMutator(PdbMutatorInterface* pdb_mutator) { |
- DCHECK(pdb_mutator != NULL); |
- pdb_mutators_.push_back(pdb_mutator); |
- return true; |
-} |
- |
-bool PERelinker::AppendPdbMutators( |
- const std::vector<PdbMutatorInterface*>& pdb_mutators) { |
- pdb_mutators_.insert(pdb_mutators_.end(), |
- pdb_mutators.begin(), |
- pdb_mutators.end()); |
- return true; |
-} |
- |
-bool PERelinker::Init() { |
- DCHECK(!inited_); |
- |
- // Initialize the paths. |
- if (!ValidateAndInferPaths(input_path_, output_path_, allow_overwrite_, |
- &input_pdb_path_, &output_pdb_path_)) { |
- return false; |
- } |
- |
- LOG(INFO) << "Input module : " << input_path_.value(); |
- LOG(INFO) << "Input PDB : " << input_pdb_path_.value(); |
- LOG(INFO) << "Output module: " << output_path_.value(); |
- LOG(INFO) << "Output PDB : " << output_pdb_path_.value(); |
- |
- // Open the input PE file. |
- if (!input_pe_file_.Init(input_path_)) { |
- LOG(ERROR) << "Unable to load \"" << input_path_.value() << "\"."; |
- return false; |
- } |
- |
- // Generate a GUID for the relinked image's PDB file. |
- if (FAILED(::CoCreateGuid(&output_guid_))) { |
- LOG(ERROR) << "Failed to create new PDB GUID."; |
- return false; |
- } |
- |
- // Decompose the image. |
- if (!Decompose(input_pe_file_, input_pdb_path_, &input_image_layout_, |
- &headers_block_)) { |
- return false; |
- } |
- |
- inited_ = true; |
- |
- return true; |
-} |
- |
-bool PERelinker::Relink() { |
- if (!inited_) { |
- LOG(ERROR) << "Init has not been successfully called."; |
- return false; |
- } |
- |
- // Apply the user supplied transforms. |
- if (!ApplyUserTransforms()) |
- return false; |
- |
- // Finalize the block-graph. This applies PE and Syzygy specific transforms. |
- if (!FinalizeBlockGraph(input_path_, output_pdb_path_, output_guid_, |
- add_metadata_, pe_transform_policy_, &block_graph_, |
- headers_block_)) { |
- return false; |
- } |
- |
- // Apply the user supplied orderers. |
- OrderedBlockGraph ordered_block_graph(&block_graph_); |
- if (!ApplyUserOrderers(&ordered_block_graph)) |
- return false; |
- |
- // Finalize the ordered block graph. This applies PE specific orderers. |
- if (!FinalizeOrderedBlockGraph(&ordered_block_graph, headers_block_)) |
- return false; |
- |
- // Lay it out. |
- ImageLayout output_image_layout(&block_graph_); |
- if (!BuildImageLayout(padding_, code_alignment_, |
- ordered_block_graph, headers_block_, |
- &output_image_layout)) { |
- return false; |
- } |
- |
- if (!ApplyUserLayoutTransforms(&output_image_layout, &ordered_block_graph)) |
- return false; |
- |
- // Write the image. |
- if (!WriteImage(output_image_layout, output_path_)) |
- return false; |
- |
- // From here on down we are processing the PDB file. |
- |
- // Read the PDB file. |
- LOG(INFO) << "Reading PDB file: " << input_pdb_path_.value(); |
- pdb::PdbReader pdb_reader; |
- PdbFile pdb_file; |
- if (!pdb_reader.Read(input_pdb_path_, &pdb_file)) { |
- LOG(ERROR) << "Unable to read PDB file: " << input_pdb_path_.value(); |
- return false; |
- } |
- |
- // Apply any user specified mutators to the PDB file. |
- if (!pdb::ApplyPdbMutators(pdb_mutators_, &pdb_file)) |
- return false; |
- |
- // Finalize the PDB file. |
- RelativeAddressRange input_range; |
- GetOmapRange(input_image_layout_.sections, &input_range); |
- if (!FinalizePdbFile(input_path_, output_path_, input_range, |
- output_image_layout, output_guid_, augment_pdb_, |
- strip_strings_, compress_pdb_, &pdb_file)) { |
- return false; |
- } |
- |
- // Write the PDB file. |
- LOG(INFO) << "Writing the PDB."; |
- pdb::PdbWriter pdb_writer; |
- if (!pdb_writer.Write(output_pdb_path_, pdb_file)) { |
- LOG(ERROR) << "Failed to write PDB file \"" << output_pdb_path_.value() |
- << "\"."; |
- return false; |
- } |
- |
- LOG(INFO) << "PE relinker finished."; |
- |
- return true; |
-} |
- |
-} // namespace pe |
+// 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. |
+ |
+#include "syzygy/pe/pe_relinker.h" |
+ |
+#include "base/files/file_util.h" |
+#include "syzygy/pdb/pdb_byte_stream.h" |
+#include "syzygy/pdb/pdb_file.h" |
+#include "syzygy/pdb/pdb_reader.h" |
+#include "syzygy/pdb/pdb_util.h" |
+#include "syzygy/pdb/pdb_writer.h" |
+#include "syzygy/pe/decomposer.h" |
+#include "syzygy/pe/metadata.h" |
+#include "syzygy/pe/pdb_info.h" |
+#include "syzygy/pe/pe_file_writer.h" |
+#include "syzygy/pe/pe_relinker_util.h" |
+#include "syzygy/pe/serialization.h" |
+ |
+namespace pe { |
+ |
+namespace { |
+ |
+typedef block_graph::BlockGraphTransformInterface Transform; |
+typedef block_graph::BlockGraphOrdererInterface Orderer; |
+ |
+using block_graph::ApplyBlockGraphTransform; |
+using block_graph::BlockGraph; |
+using block_graph::OrderedBlockGraph; |
+using core::RelativeAddress; |
+using pdb::NameStreamMap; |
+using pdb::PdbByteStream; |
+using pdb::PdbFile; |
+using pdb::PdbInfoHeader70; |
+using pdb::PdbMutatorInterface; |
+using pdb::PdbStream; |
+using pdb::WritablePdbStream; |
+ |
+// Decomposes the module enclosed by the given PE file. |
+bool Decompose(const PEFile& pe_file, |
+ const base::FilePath& pdb_path, |
+ ImageLayout* image_layout, |
+ BlockGraph::Block** dos_header_block) { |
+ DCHECK(image_layout != NULL); |
+ DCHECK(dos_header_block != NULL); |
+ |
+ LOG(INFO) << "Decomposing module: " << pe_file.path().value(); |
+ |
+ BlockGraph* block_graph = image_layout->blocks.graph(); |
+ ImageLayout orig_image_layout(block_graph); |
+ |
+ // Decompose the input image. |
+ Decomposer decomposer(pe_file); |
+ decomposer.set_pdb_path(pdb_path); |
+ if (!decomposer.Decompose(&orig_image_layout)) { |
+ LOG(ERROR) << "Unable to decompose module: " << pe_file.path().value(); |
+ return false; |
+ } |
+ |
+ // Make a copy of the image layout without padding. We don't want to carry |
+ // the padding through the toolchain. |
+ LOG(INFO) << "Removing padding blocks."; |
+ if (!pe::CopyImageLayoutWithoutPadding(orig_image_layout, image_layout)) { |
+ LOG(ERROR) << "Failed to remove padding blocks."; |
+ return false; |
+ } |
+ |
+ // Get the DOS header block. |
+ *dos_header_block = |
+ image_layout->blocks.GetBlockByAddress( |
+ BlockGraph::RelativeAddress(0)); |
+ if (*dos_header_block == NULL) { |
+ LOG(ERROR) << "Unable to find the DOS header block."; |
+ return false; |
+ } |
+ |
+ return true; |
+} |
+ |
+// Writes the image. |
+bool WriteImage(const ImageLayout& image_layout, |
+ const base::FilePath& output_path) { |
+ PEFileWriter writer(image_layout); |
+ |
+ LOG(INFO) << "Writing image: " << output_path.value(); |
+ if (!writer.WriteImage(output_path)) { |
+ LOG(ERROR) << "Failed to write image \"" << output_path.value() << "\"."; |
+ return false; |
+ } |
+ |
+ return true; |
+} |
+ |
+} // namespace |
+ |
+PERelinker::PERelinker(const PETransformPolicy* pe_transform_policy) |
+ : PECoffRelinker(pe_transform_policy), |
+ pe_transform_policy_(pe_transform_policy), |
+ add_metadata_(true), augment_pdb_(true), |
+ compress_pdb_(false), strip_strings_(false), |
+ padding_(0), code_alignment_(1), output_guid_(GUID_NULL) { |
+ DCHECK(pe_transform_policy != NULL); |
+} |
+ |
+bool PERelinker::AppendPdbMutator(PdbMutatorInterface* pdb_mutator) { |
+ DCHECK(pdb_mutator != NULL); |
+ pdb_mutators_.push_back(pdb_mutator); |
+ return true; |
+} |
+ |
+bool PERelinker::AppendPdbMutators( |
+ const std::vector<PdbMutatorInterface*>& pdb_mutators) { |
+ pdb_mutators_.insert(pdb_mutators_.end(), |
+ pdb_mutators.begin(), |
+ pdb_mutators.end()); |
+ return true; |
+} |
+ |
+bool PERelinker::Init() { |
+ DCHECK(!inited_); |
+ |
+ // Initialize the paths. |
+ if (!ValidateAndInferPaths(input_path_, output_path_, allow_overwrite_, |
+ &input_pdb_path_, &output_pdb_path_)) { |
+ return false; |
+ } |
+ |
+ LOG(INFO) << "Input module : " << input_path_.value(); |
+ LOG(INFO) << "Input PDB : " << input_pdb_path_.value(); |
+ LOG(INFO) << "Output module: " << output_path_.value(); |
+ LOG(INFO) << "Output PDB : " << output_pdb_path_.value(); |
+ |
+ // Open the input PE file. |
+ if (!input_pe_file_.Init(input_path_)) { |
+ LOG(ERROR) << "Unable to load \"" << input_path_.value() << "\"."; |
+ return false; |
+ } |
+ |
+ // Generate a GUID for the relinked image's PDB file. |
+ if (FAILED(::CoCreateGuid(&output_guid_))) { |
+ LOG(ERROR) << "Failed to create new PDB GUID."; |
+ return false; |
+ } |
+ |
+ // Decompose the image. |
+ if (!Decompose(input_pe_file_, input_pdb_path_, &input_image_layout_, |
+ &headers_block_)) { |
+ return false; |
+ } |
+ |
+ inited_ = true; |
+ |
+ return true; |
+} |
+ |
+bool PERelinker::Relink() { |
+ if (!inited_) { |
+ LOG(ERROR) << "Init has not been successfully called."; |
+ return false; |
+ } |
+ |
+ // Apply the user supplied transforms. |
+ if (!ApplyUserTransforms()) |
+ return false; |
+ |
+ // Finalize the block-graph. This applies PE and Syzygy specific transforms. |
+ if (!FinalizeBlockGraph(input_path_, output_pdb_path_, output_guid_, |
+ add_metadata_, pe_transform_policy_, &block_graph_, |
+ headers_block_)) { |
+ return false; |
+ } |
+ |
+ // Apply the user supplied orderers. |
+ OrderedBlockGraph ordered_block_graph(&block_graph_); |
+ if (!ApplyUserOrderers(&ordered_block_graph)) |
+ return false; |
+ |
+ // Finalize the ordered block graph. This applies PE specific orderers. |
+ if (!FinalizeOrderedBlockGraph(&ordered_block_graph, headers_block_)) |
+ return false; |
+ |
+ // Lay it out. |
+ ImageLayout output_image_layout(&block_graph_); |
+ if (!BuildImageLayout(padding_, code_alignment_, |
+ ordered_block_graph, headers_block_, |
+ &output_image_layout)) { |
+ return false; |
+ } |
+ |
+ if (!ApplyUserLayoutTransforms(&output_image_layout, &ordered_block_graph)) |
+ return false; |
+ |
+ // Write the image. |
+ if (!WriteImage(output_image_layout, output_path_)) |
+ return false; |
+ |
+ // From here on down we are processing the PDB file. |
+ |
+ // Read the PDB file. |
+ LOG(INFO) << "Reading PDB file: " << input_pdb_path_.value(); |
+ pdb::PdbReader pdb_reader; |
+ PdbFile pdb_file; |
+ if (!pdb_reader.Read(input_pdb_path_, &pdb_file)) { |
+ LOG(ERROR) << "Unable to read PDB file: " << input_pdb_path_.value(); |
+ return false; |
+ } |
+ |
+ // Apply any user specified mutators to the PDB file. |
+ if (!pdb::ApplyPdbMutators(pdb_mutators_, &pdb_file)) |
+ return false; |
+ |
+ // Finalize the PDB file. |
+ RelativeAddressRange input_range; |
+ GetOmapRange(input_image_layout_.sections, &input_range); |
+ if (!FinalizePdbFile(input_path_, output_path_, input_range, |
+ output_image_layout, output_guid_, augment_pdb_, |
+ strip_strings_, compress_pdb_, &pdb_file)) { |
+ return false; |
+ } |
+ |
+ // Write the PDB file. |
+ LOG(INFO) << "Writing the PDB."; |
+ pdb::PdbWriter pdb_writer; |
+ if (!pdb_writer.Write(output_pdb_path_, pdb_file)) { |
+ LOG(ERROR) << "Failed to write PDB file \"" << output_pdb_path_.value() |
+ << "\"."; |
+ return false; |
+ } |
+ |
+ LOG(INFO) << "PE relinker finished."; |
+ |
+ return true; |
+} |
+ |
+} // namespace pe |