1 : // Copyright 2013 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 : // Implementation of utility functions for finding the original PE file from
16 : // a Syzygy transformed/instrumented version of it.
17 :
18 : #include "syzygy/grinder/find.h"
19 :
20 : #include "syzygy/pe/find.h"
21 : #include "syzygy/pe/metadata.h"
22 :
23 : namespace grinder {
24 :
25 : bool PeFilesAreRelated(const base::FilePath& transformed_pe_path,
26 E : const base::FilePath& original_pe_path) {
27 E : pe::PEFile transformed_pe_file;
28 E : if (!transformed_pe_file.Init(transformed_pe_path)) {
29 E : LOG(ERROR) << "Unable to parse PE file: " << transformed_pe_path.value();
30 E : return false;
31 : }
32 :
33 E : pe::Metadata metadata;
34 E : if (!metadata.LoadFromPE(transformed_pe_file)) {
35 E : LOG(ERROR) << "Unable to load metadata from PE file: "
36 : << transformed_pe_path.value();
37 E : return false;
38 : }
39 :
40 E : pe::PEFile original_pe_file;
41 E : if (!original_pe_file.Init(original_pe_path)) {
42 E : LOG(ERROR) << "Unable to parse PE file: " << original_pe_path.value();
43 E : return false;
44 : }
45 :
46 E : pe::PEFile::Signature original_signature;
47 E : original_pe_file.GetSignature(&original_signature);
48 E : if (!metadata.module_signature().IsConsistent(original_signature))
49 E : return false;
50 :
51 E : return true;
52 E : }
53 :
54 : bool FindOriginalPeFile(const base::FilePath& transformed_pe_path,
55 E : base::FilePath* original_pe_path) {
56 E : DCHECK(original_pe_path != NULL);
57 : return FindOriginalPeFile(transformed_pe_path,
58 : L"",
59 E : original_pe_path);
60 E : }
61 :
62 : bool FindOriginalPeFile(const base::FilePath& transformed_pe_path,
63 : const base::StringPiece16& search_paths,
64 E : base::FilePath* original_pe_path) {
65 E : DCHECK(original_pe_path != NULL);
66 :
67 E : pe::PEFile transformed_pe_file;
68 E : if (!transformed_pe_file.Init(transformed_pe_path)) {
69 E : LOG(ERROR) << "Unable to parse PE file: " << transformed_pe_path.value();
70 E : return false;
71 : }
72 :
73 E : pe::Metadata metadata;
74 E : if (!metadata.LoadFromPE(transformed_pe_file)) {
75 E : LOG(ERROR) << "Unable to load metadata from PE file: "
76 : << transformed_pe_path.value();
77 E : return false;
78 : }
79 :
80 E : std::vector<base::FilePath> candidate_paths;
81 E : if (!original_pe_path->empty())
82 E : candidate_paths.push_back(*original_pe_path);
83 E : candidate_paths.push_back(base::FilePath(metadata.module_signature().path));
84 :
85 : // Search using each of the candidate paths as a base.
86 E : for (size_t i = 0; i < candidate_paths.size(); ++i) {
87 E : const base::FilePath& path = candidate_paths[i];
88 :
89 E : *original_pe_path = path;
90 : if (!FindModuleBySignature(metadata.module_signature(),
91 : search_paths,
92 E : original_pe_path)) {
93 i : return false;
94 : }
95 :
96 : // We can terminate the search early if the module is found.
97 E : if (!original_pe_path->empty())
98 E : return true;
99 i : }
100 i : DCHECK(original_pe_path->empty());
101 :
102 i : return true;
103 E : }
104 :
105 : } // namespace grinder
|