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/zap_timestamp/zap_timestamp.h"
16 :
17 : #include "base/files/file_util.h"
18 : #include "base/files/scoped_temp_dir.h"
19 : #include "gtest/gtest.h"
20 : #include "syzygy/core/unittest_util.h"
21 : #include "syzygy/pe/unittest_util.h"
22 :
23 : namespace zap_timestamp {
24 :
25 : namespace {
26 :
27 : // We don't bother with having specific data for the 'Coverage' case.
28 : #define TEST_DATA_PREFIX_0 L"syzygy\\zap_timestamp\\test_data\\"
29 : #ifdef NDEBUG
30 : #define TEST_DATA_PREFIX_1 L"Release\\"
31 : #else
32 : #define TEST_DATA_PREFIX_1 L"Debug\\"
33 : #endif
34 : #define TEST_DATA_PREFIX TEST_DATA_PREFIX_0 TEST_DATA_PREFIX_1
35 :
36 : struct RawPePdbPathPair {
37 : const wchar_t* pe_path;
38 : const wchar_t* pdb_path;
39 : };
40 : RawPePdbPathPair kRawTestPaths[] = {
41 : { TEST_DATA_PREFIX L"copy0\\test_dll.dll",
42 : TEST_DATA_PREFIX L"copy0\\test_dll.pdb" },
43 : { TEST_DATA_PREFIX L"copy1\\test_dll.dll",
44 : TEST_DATA_PREFIX L"copy1\\test_dll.pdb" },
45 : { TEST_DATA_PREFIX L"copy2\\test_dll.dll",
46 : TEST_DATA_PREFIX L"copy2\\test_dll.pdb" } };
47 :
48 : struct PePdbPathPair {
49 : base::FilePath pe_path;
50 : base::FilePath pdb_path;
51 : };
52 :
53 : class ZapTimestampTest : public testing::Test {
54 : public:
55 E : virtual void SetUp() override {
56 E : testing::Test::SetUp();
57 :
58 E : temp_dir_.CreateUniqueTempDir();
59 :
60 : // Get the full test data paths.
61 E : for (size_t i = 0; i < arraysize(kRawTestPaths); ++i) {
62 E : PePdbPathPair pair;
63 E : pair.pe_path = testing::GetSrcRelativePath(kRawTestPaths[i].pe_path);
64 E : pair.pdb_path = testing::GetSrcRelativePath(kRawTestPaths[i].pdb_path);
65 E : test_paths_.push_back(pair);
66 E : }
67 :
68 E : temp_pe_path_ = temp_dir_.path().Append(L"test_dll.dll");
69 E : temp_pdb_path_ = temp_dir_.path().Append(L"test_dll.pdb");
70 E : }
71 :
72 : void CopyTestData(const base::FilePath& pe_path,
73 E : const base::FilePath& pdb_path) {
74 E : ASSERT_TRUE(base::CopyFile(pe_path, temp_pe_path_));
75 E : ASSERT_TRUE(base::CopyFile(pdb_path, temp_pdb_path_));
76 E : }
77 :
78 E : void CopyTestData(size_t index) {
79 E : ASSERT_GT(test_paths_.size(), index);
80 E : ASSERT_NO_FATAL_FAILURE(CopyTestData(
81 : test_paths_[index].pe_path, test_paths_[index].pdb_path));
82 E : }
83 :
84 E : void CopyNoPdbTestData() {
85 : base::FilePath pe_path = testing::GetSrcRelativePath(
86 E : L"syzygy\\zap_timestamp\\test_data\\test_dll_no_pdb.dll");
87 E : temp_pe_path_ = temp_dir_.path().Append(L"test_dll_no_pdb.dll");
88 E : temp_pdb_path_.clear();
89 E : ASSERT_TRUE(base::CopyFileW(pe_path, temp_pe_path_));
90 E : }
91 :
92 : base::ScopedTempDir temp_dir_;
93 : std::vector<PePdbPathPair> test_paths_;
94 :
95 : base::FilePath temp_pe_path_;
96 : base::FilePath temp_pdb_path_;
97 : };
98 :
99 : } // namespace
100 :
101 E : TEST_F(ZapTimestampTest, InitFailsForNonExistentPath) {
102 E : ZapTimestamp zap;
103 E : zap.set_input_image(base::FilePath(L"nonexistent_pe_file.dll"));
104 E : zap.set_overwrite(true);
105 E : EXPECT_FALSE(zap.Init());
106 E : }
107 :
108 E : TEST_F(ZapTimestampTest, InitFailsForMismatchedPeAndPdb) {
109 : ASSERT_NO_FATAL_FAILURE(CopyTestData(
110 E : test_paths_[0].pe_path, test_paths_[1].pdb_path));
111 E : ZapTimestamp zap;
112 E : zap.set_input_image(temp_pe_path_);
113 E : zap.set_overwrite(true);
114 E : EXPECT_FALSE(zap.Init());
115 E : }
116 :
117 E : TEST_F(ZapTimestampTest, InitFailsWithMissingPdb) {
118 E : ASSERT_NO_FATAL_FAILURE(CopyTestData(0));
119 E : ASSERT_TRUE(base::DeleteFile(temp_pdb_path_, false));
120 E : ZapTimestamp zap;
121 E : zap.set_input_image(temp_pe_path_);
122 E : zap.set_overwrite(true);
123 E : EXPECT_FALSE(zap.Init());
124 E : }
125 :
126 E : TEST_F(ZapTimestampTest, InitAutoFindPdb) {
127 E : ASSERT_NO_FATAL_FAILURE(CopyTestData(0));
128 E : ZapTimestamp zap;
129 E : zap.set_input_image(temp_pe_path_);
130 E : zap.set_overwrite(true);
131 E : EXPECT_TRUE(zap.Init());
132 E : EXPECT_EQ(temp_pdb_path_, zap.input_pdb());
133 E : }
134 :
135 E : TEST_F(ZapTimestampTest, InitExplicitPdb) {
136 E : ASSERT_NO_FATAL_FAILURE(CopyTestData(0));
137 E : ZapTimestamp zap;
138 E : zap.set_input_image(temp_pe_path_);
139 E : zap.set_input_pdb(temp_pdb_path_);
140 E : zap.set_overwrite(true);
141 E : EXPECT_TRUE(zap.Init());
142 E : }
143 :
144 E : TEST_F(ZapTimestampTest, IsIdempotent) {
145 : // Zap the first set of the PE and PDB files.
146 E : ASSERT_NO_FATAL_FAILURE(CopyTestData(0));
147 E : ZapTimestamp zap0;
148 E : zap0.set_input_image(temp_pe_path_);
149 E : zap0.set_overwrite(true);
150 E : EXPECT_TRUE(zap0.Init());
151 E : EXPECT_EQ(temp_pdb_path_, zap0.output_pdb());
152 E : EXPECT_TRUE(zap0.Zap());
153 :
154 : // Make a copy of the singly zapped files.
155 E : base::FilePath pe_path_0 = temp_dir_.path().Append(L"test_dll_0.dll");
156 E : base::FilePath pdb_path_0 = temp_dir_.path().Append(L"test_dll_0.pdb");
157 E : ASSERT_TRUE(base::CopyFile(temp_pe_path_, pe_path_0));
158 E : ASSERT_TRUE(base::CopyFile(temp_pdb_path_, pdb_path_0));
159 :
160 : // Zap them again.
161 E : ZapTimestamp zap1;
162 E : zap1.set_input_image(temp_pe_path_);
163 E : zap1.set_overwrite(true);
164 E : EXPECT_TRUE(zap1.Init());
165 E : EXPECT_EQ(temp_pdb_path_, zap1.output_pdb());
166 E : EXPECT_TRUE(zap1.Zap());
167 :
168 : // The singly and doubly zapped files should be the same.
169 E : EXPECT_TRUE(base::ContentsEqual(temp_pe_path_, pe_path_0));
170 E : EXPECT_TRUE(base::ContentsEqual(temp_pdb_path_, pdb_path_0));
171 E : }
172 :
173 E : TEST_F(ZapTimestampTest, SucceedsInferPdb) {
174 E : ASSERT_NO_FATAL_FAILURE(CopyTestData(0));
175 E : base::FilePath pe_path = temp_dir_.path().Append(L"test_dll.new.dll");
176 E : base::FilePath pdb_path = temp_dir_.path().Append(L"test_dll.new.dll.pdb");
177 :
178 : // Zap the image. Let the PDB output be inferred.
179 E : ZapTimestamp zap0;
180 E : zap0.set_input_image(temp_pe_path_);
181 E : zap0.set_output_image(pe_path);
182 E : EXPECT_TRUE(zap0.Init());
183 E : EXPECT_TRUE(zap0.Zap());
184 E : EXPECT_TRUE(base::PathExists(pe_path));
185 E : EXPECT_TRUE(base::PathExists(pdb_path));
186 E : }
187 :
188 E : TEST_F(ZapTimestampTest, SucceedsExplicitPdb) {
189 E : ASSERT_NO_FATAL_FAILURE(CopyTestData(0));
190 E : base::FilePath pe_path = temp_dir_.path().Append(L"test_dll.new.dll");
191 E : base::FilePath pdb_path = temp_dir_.path().Append(L"test_dll.new.dll.pdb");
192 :
193 : // Zap the image. Provide an explicit output PDB.
194 E : ZapTimestamp zap0;
195 E : zap0.set_input_image(temp_pe_path_);
196 E : zap0.set_output_image(pe_path);
197 E : zap0.set_output_pdb(pdb_path);
198 E : EXPECT_TRUE(zap0.Init());
199 E : EXPECT_TRUE(zap0.Zap());
200 E : EXPECT_TRUE(base::PathExists(pe_path));
201 E : EXPECT_TRUE(base::PathExists(pdb_path));
202 E : }
203 :
204 E : TEST_F(ZapTimestampTest, SucceedsDontWritePdb) {
205 E : ASSERT_NO_FATAL_FAILURE(CopyTestData(0));
206 E : base::FilePath pe_path = temp_dir_.path().Append(L"test_dll.new.dll");
207 E : base::FilePath pdb_path = temp_dir_.path().Append(L"test_dll.new.dll.pdb");
208 :
209 : // Zap the image. Let the PDB output be inferred.
210 E : ZapTimestamp zap0;
211 E : zap0.set_input_image(temp_pe_path_);
212 E : zap0.set_output_image(pe_path);
213 E : zap0.set_write_pdb(false);
214 E : EXPECT_TRUE(zap0.Init());
215 E : EXPECT_TRUE(zap0.Zap());
216 E : EXPECT_TRUE(base::PathExists(pe_path));
217 E : EXPECT_FALSE(base::PathExists(pdb_path));
218 E : }
219 :
220 E : TEST_F(ZapTimestampTest, SucceedsDontWriteImage) {
221 E : ASSERT_NO_FATAL_FAILURE(CopyTestData(0));
222 E : base::FilePath pe_path = temp_dir_.path().Append(L"test_dll.new.dll");
223 E : base::FilePath pdb_path = temp_dir_.path().Append(L"test_dll.new.dll.pdb");
224 :
225 : // Zap the image. Let the PDB output be inferred.
226 E : ZapTimestamp zap0;
227 E : zap0.set_input_image(temp_pe_path_);
228 E : zap0.set_output_image(pe_path);
229 E : zap0.set_write_image(false);
230 E : EXPECT_TRUE(zap0.Init());
231 E : EXPECT_TRUE(zap0.Zap());
232 E : EXPECT_FALSE(base::PathExists(pe_path));
233 E : EXPECT_TRUE(base::PathExists(pdb_path));
234 E : }
235 :
236 E : TEST_F(ZapTimestampTest, FailsBecauseWouldOverwritePe) {
237 E : ASSERT_NO_FATAL_FAILURE(CopyTestData(0));
238 E : base::FilePath pe_path = temp_dir_.path().Append(L"test_dll.new.dll");
239 E : base::FilePath pdb_path = temp_dir_.path().Append(L"test_dll.new.dll.pdb");
240 :
241 E : base::WriteFile(pe_path, "h", 1);
242 :
243 : // Zap the image. Let the PDB output be inferred.
244 E : ZapTimestamp zap0;
245 E : zap0.set_input_image(temp_pe_path_);
246 E : zap0.set_output_image(pe_path);
247 E : EXPECT_FALSE(zap0.Init());
248 E : }
249 :
250 E : TEST_F(ZapTimestampTest, FailsBecauseWouldOverwritePdb) {
251 E : ASSERT_NO_FATAL_FAILURE(CopyTestData(0));
252 E : base::FilePath pe_path = temp_dir_.path().Append(L"test_dll.new.dll");
253 E : base::FilePath pdb_path = temp_dir_.path().Append(L"test_dll.new.dll.pdb");
254 :
255 E : base::WriteFile(pdb_path, "h", 1);
256 :
257 : // Zap the image. Let the PDB output be inferred.
258 E : ZapTimestamp zap0;
259 E : zap0.set_input_image(temp_pe_path_);
260 E : zap0.set_output_image(pe_path);
261 E : EXPECT_FALSE(zap0.Init());
262 E : }
263 :
264 E : TEST_F(ZapTimestampTest, Succeeds) {
265 : // Zap the first set of the PE and PDB files.
266 E : ASSERT_NO_FATAL_FAILURE(CopyTestData(0));
267 E : ZapTimestamp zap0;
268 E : zap0.set_input_image(temp_pe_path_);
269 E : zap0.set_overwrite(true);
270 E : EXPECT_TRUE(zap0.Init());
271 E : EXPECT_EQ(temp_pdb_path_, zap0.input_pdb());
272 E : EXPECT_TRUE(zap0.Zap());
273 :
274 : // Rename and move the PE and PDB file.
275 E : base::FilePath pe_path_0 = temp_dir_.path().Append(L"test_dll_0.dll");
276 E : base::FilePath pdb_path_0 = temp_dir_.path().Append(L"test_dll_0.pdb");
277 E : ASSERT_TRUE(base::Move(temp_pe_path_, pe_path_0));
278 E : ASSERT_TRUE(base::Move(temp_pdb_path_, pdb_path_0));
279 :
280 : // Zap the second set of the PE and PDB files.
281 E : ASSERT_NO_FATAL_FAILURE(CopyTestData(1));
282 E : ZapTimestamp zap1;
283 E : zap1.set_input_image(temp_pe_path_);
284 E : zap1.set_input_pdb(temp_pdb_path_);
285 E : zap1.set_overwrite(true);
286 E : EXPECT_TRUE(zap1.Init());
287 E : EXPECT_TRUE(zap1.Zap());
288 :
289 : // Rename and move the PE and PDB file.
290 E : base::FilePath pe_path_1 = temp_dir_.path().Append(L"test_dll_1.dll");
291 E : base::FilePath pdb_path_1 = temp_dir_.path().Append(L"test_dll_1.pdb");
292 E : ASSERT_TRUE(base::Move(temp_pe_path_, pe_path_1));
293 E : ASSERT_TRUE(base::Move(temp_pdb_path_, pdb_path_1));
294 :
295 : // Zap the third set of the PE and PDB files.
296 E : ASSERT_NO_FATAL_FAILURE(CopyTestData(2));
297 E : ZapTimestamp zap2;
298 E : zap2.set_input_image(temp_pe_path_);
299 E : zap2.set_input_pdb(temp_pdb_path_);
300 E : zap2.set_overwrite(true);
301 E : EXPECT_TRUE(zap2.Init());
302 E : EXPECT_TRUE(zap2.Zap());
303 :
304 : // The sets of zapped files should match.
305 E : EXPECT_TRUE(base::ContentsEqual(temp_pe_path_, pe_path_0));
306 E : EXPECT_TRUE(base::ContentsEqual(temp_pe_path_, pe_path_1));
307 E : EXPECT_TRUE(base::ContentsEqual(temp_pdb_path_, pdb_path_0));
308 E : EXPECT_TRUE(base::ContentsEqual(temp_pdb_path_, pdb_path_1));
309 E : }
310 :
311 E : TEST_F(ZapTimestampTest, IsIdempotentNoPdb) {
312 : // Zap the iage.
313 E : ASSERT_NO_FATAL_FAILURE(CopyNoPdbTestData());
314 E : ZapTimestamp zap0;
315 E : zap0.set_input_image(temp_pe_path_);
316 E : zap0.set_overwrite(true);
317 E : zap0.set_write_pdb(false);
318 E : EXPECT_TRUE(zap0.Init());
319 E : EXPECT_TRUE(zap0.Zap());
320 :
321 : // Make a copy of the singly zapped image.
322 E : base::FilePath pe_path_0 = temp_dir_.path().Append(L"test_dll_no_pdb_0.dll");
323 E : ASSERT_TRUE(base::CopyFile(temp_pe_path_, pe_path_0));
324 :
325 : // Zap it again.
326 E : ZapTimestamp zap1;
327 E : zap1.set_input_image(temp_pe_path_);
328 E : zap1.set_overwrite(true);
329 E : zap1.set_write_pdb(false);
330 E : EXPECT_TRUE(zap1.Init());
331 E : EXPECT_TRUE(zap1.Zap());
332 :
333 : // The singly and doubly zapped files should be the same.
334 E : EXPECT_TRUE(base::ContentsEqual(temp_pe_path_, pe_path_0));
335 E : }
336 :
337 : } // namespace zap_timestamp
|