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/pe_file.h"
16 :
17 : #include "base/native_library.h"
18 : #include "base/path_service.h"
19 : #include "base/files/file_path.h"
20 : #include "base/strings/string_util.h"
21 : #include "gmock/gmock.h"
22 : #include "gtest/gtest.h"
23 : #include "syzygy/core/unittest_util.h"
24 : #include "syzygy/pe/unittest_util.h"
25 :
26 : namespace pe {
27 :
28 : namespace {
29 :
30 : using core::AbsoluteAddress;
31 : using core::FileOffsetAddress;
32 : using core::RelativeAddress;
33 : using core::SectionOffsetAddress;
34 :
35 : class PEFileTest: public testing::PELibUnitTest {
36 : typedef testing::PELibUnitTest Super;
37 :
38 : public:
39 E : PEFileTest() : test_dll_(NULL) {
40 E : }
41 :
42 E : virtual void SetUp() override {
43 E : Super::SetUp();
44 :
45 : base::FilePath test_dll =
46 E : testing::GetExeRelativePath(testing::kTestDllName);
47 E : base::NativeLibraryLoadError error;
48 E : test_dll_ = base::LoadNativeLibrary(test_dll, &error);
49 :
50 E : ASSERT_TRUE(image_file_.Init(test_dll));
51 :
52 : base::FilePath test_dll_64 =
53 E : testing::GetExeRelativePath(testing::kTestDllName64);
54 E : test_dll_64_ = base::LoadNativeLibrary(test_dll_64, &error);
55 :
56 E : ASSERT_TRUE(image_file_64_.Init(test_dll_64));
57 E : }
58 :
59 E : virtual void TearDown() override {
60 E : base::UnloadNativeLibrary(test_dll_);
61 E : base::UnloadNativeLibrary(test_dll_64_);
62 E : Super::TearDown();
63 E : }
64 :
65 : void TestAddressesAreConsistent(RelativeAddress rel,
66 : AbsoluteAddress abs,
67 : FileOffsetAddress off,
68 E : SectionOffsetAddress sect_off) {
69 E : AbsoluteAddress abs2;
70 E : RelativeAddress rel2;
71 E : FileOffsetAddress off2;
72 E : SectionOffsetAddress sect_off2;
73 :
74 E : ASSERT_TRUE(image_file_.Translate(rel, &abs2));
75 E : ASSERT_EQ(abs, abs2);
76 :
77 E : ASSERT_TRUE(image_file_.Translate(abs, &rel2));
78 E : ASSERT_EQ(rel, rel2);
79 :
80 E : ASSERT_TRUE(image_file_.Translate(off, &rel2));
81 E : ASSERT_EQ(rel, rel2);
82 :
83 E : ASSERT_TRUE(image_file_.Translate(rel, &off2));
84 E : ASSERT_EQ(off, off2);
85 :
86 E : ASSERT_TRUE(image_file_.Translate(rel, §_off2));
87 E : ASSERT_EQ(sect_off, sect_off2);
88 E : }
89 :
90 : protected:
91 : pe::PEFile image_file_;
92 : pe::PEFile64 image_file_64_;
93 : base::NativeLibrary test_dll_;
94 : base::NativeLibrary test_dll_64_;
95 : };
96 :
97 : // Functor for comparing import infos.
98 : struct CompareImportInfo {
99 : bool operator()(const PEFile::ImportInfo& ii1,
100 E : const PEFile::ImportInfo& ii2) {
101 E : if (ii1.hint < ii2.hint)
102 E : return true;
103 E : if (ii1.hint > ii2.hint)
104 i : return false;
105 E : if (ii1.ordinal < ii2.ordinal)
106 E : return true;
107 i : if (ii1.ordinal > ii2.ordinal)
108 i : return false;
109 i : return ii1.function < ii2.function;
110 E : }
111 : };
112 :
113 : } // namespace
114 :
115 E : TEST_F(PEFileTest, Create) {
116 E : PEFile image_file;
117 :
118 E : ASSERT_EQ(NULL, image_file.dos_header());
119 E : ASSERT_EQ(NULL, image_file.nt_headers());
120 E : ASSERT_EQ(NULL, image_file.section_headers());
121 E : }
122 :
123 E : TEST_F(PEFileTest, Init) {
124 E : EXPECT_TRUE(image_file_.dos_header() != NULL);
125 E : EXPECT_TRUE(image_file_.nt_headers() != NULL);
126 E : EXPECT_TRUE(image_file_.section_headers() != NULL);
127 E : }
128 :
129 E : TEST_F(PEFileTest, GetImageData) {
130 E : const IMAGE_NT_HEADERS* nt_headers = image_file_.nt_headers();
131 E : ASSERT_TRUE(nt_headers != NULL);
132 : const IMAGE_DATA_DIRECTORY* exports =
133 E : &nt_headers->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT];
134 :
135 : // We should be able to read the export directory.
136 : ASSERT_TRUE(image_file_.GetImageData(RelativeAddress(exports->VirtualAddress),
137 E : exports->Size) != NULL);
138 :
139 : // We should be able to read it using an absolute address as well.
140 E : AbsoluteAddress abs_addr;
141 : ASSERT_TRUE(image_file_.Translate(RelativeAddress(exports->VirtualAddress),
142 E : &abs_addr));
143 E : ASSERT_TRUE(image_file_.GetImageData(abs_addr, exports->Size) != NULL);
144 :
145 : // But there ought to be a gap in the image data past the header size.
146 : ASSERT_TRUE(image_file_.GetImageData(
147 E : RelativeAddress(nt_headers->OptionalHeader.SizeOfHeaders), 1) == NULL);
148 E : }
149 :
150 E : TEST_F(PEFileTest, ReadImage) {
151 E : const IMAGE_NT_HEADERS* nt_headers = image_file_.nt_headers();
152 E : ASSERT_TRUE(nt_headers != NULL);
153 : const IMAGE_DATA_DIRECTORY* exports =
154 E : &nt_headers->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT];
155 :
156 : // We should be able to read the export directory.
157 E : IMAGE_EXPORT_DIRECTORY export_dir = {};
158 : ASSERT_TRUE(image_file_.ReadImage(RelativeAddress(exports->VirtualAddress),
159 : &export_dir,
160 E : sizeof(export_dir)));
161 :
162 : // Check that we actually read something.
163 E : IMAGE_EXPORT_DIRECTORY zero_export_dir = {};
164 E : ASSERT_NE(0, memcmp(&export_dir, &zero_export_dir, sizeof(export_dir)));
165 :
166 : // Now test the ReadImageString function.
167 E : std::vector<RelativeAddress> names(export_dir.NumberOfNames);
168 : ASSERT_TRUE(image_file_.ReadImage(RelativeAddress(export_dir.AddressOfNames),
169 : &names.at(0),
170 E : sizeof(names[0]) * names.size()));
171 :
172 : // Test the same thing using an absolute address.
173 E : AbsoluteAddress abs_names_addr;
174 : ASSERT_TRUE(image_file_.Translate(RelativeAddress(export_dir.AddressOfNames),
175 E : &abs_names_addr));
176 E : std::vector<RelativeAddress> names2(export_dir.NumberOfNames);
177 : ASSERT_TRUE(image_file_.ReadImage(abs_names_addr, &names2.at(0),
178 E : sizeof(names2[0]) * names2.size()));
179 E : ASSERT_EQ(names, names2);
180 :
181 : // Read all the export name strings.
182 E : for (size_t i = 0; i < names.size(); ++i) {
183 E : std::string name1;
184 E : ASSERT_TRUE(image_file_.ReadImageString(names[i], &name1));
185 : ASSERT_TRUE(name1 == "function1" ||
186 : name1 == "function3" ||
187 : name1 == "DllMain" ||
188 : name1 == "CreateFileW" ||
189 : name1 == "TestUnusedFuncs" ||
190 : name1 == "TestExport" ||
191 : name1 == "LabelTestFunc" ||
192 : name1 == "BringInOle32DelayLib" ||
193 : name1 == "TestFunctionWithNoPrivateSymbols" ||
194 : name1 == "FuncWithOffsetOutOfImage" ||
195 E : name1 == "EndToEndTest");
196 :
197 E : std::string name2;
198 E : AbsoluteAddress abs_addr;
199 E : ASSERT_TRUE(image_file_.Translate(names[i], &abs_addr));
200 E : ASSERT_TRUE(image_file_.ReadImageString(abs_addr, &name2));
201 E : ASSERT_EQ(name1, name2);
202 E : }
203 E : }
204 :
205 E : TEST_F(PEFileTest, Contains) {
206 E : RelativeAddress relative_base(0);
207 E : AbsoluteAddress absolute_base;
208 E : size_t image_size = image_file_.nt_headers()->OptionalHeader.SizeOfImage;
209 E : RelativeAddress relative_end(image_size);
210 : AbsoluteAddress absolute_end(
211 E : image_file_.nt_headers()->OptionalHeader.ImageBase + image_size);
212 :
213 E : ASSERT_TRUE(image_file_.Translate(relative_base, &absolute_base));
214 E : ASSERT_TRUE(image_file_.Contains(relative_base, 1));
215 E : ASSERT_TRUE(image_file_.Contains(absolute_base, 1));
216 E : ASSERT_FALSE(image_file_.Contains(absolute_base - 1, 1));
217 E : ASSERT_FALSE(image_file_.Contains(absolute_end, 1));
218 E : ASSERT_FALSE(image_file_.Contains(relative_end, 1));
219 :
220 : // TODO(rogerm): test for inclusion at the end of the address space
221 : // The way the address space is built only captures the ranges
222 : // specified as sections in the headers, not the overall image size.
223 : // Either the test needs to be more invasive or the data structure
224 : // needs to be more broadly representative. Note sure which, but
225 : // it's not critical.
226 :
227 : // ASSERT_TRUE(image_file_.Contains(absolute_end - 1, 1));
228 E : }
229 :
230 E : TEST_F(PEFileTest, Translate) {
231 : // Try an address inside the headers (outside of any section).
232 E : AbsoluteAddress abs(image_file_.nt_headers()->OptionalHeader.ImageBase + 3);
233 E : RelativeAddress rel(3);
234 E : FileOffsetAddress off(3);
235 E : SectionOffsetAddress sect_off(0, 3);
236 E : ASSERT_NO_FATAL_FAILURE(TestAddressesAreConsistent(rel, abs, off, sect_off));
237 :
238 : // Now try an address in each of the sections.
239 E : size_t i = 0;
240 E : for (; i < image_file_.nt_headers()->FileHeader.NumberOfSections; ++i) {
241 E : const IMAGE_SECTION_HEADER* section = image_file_.section_header(i);
242 :
243 : AbsoluteAddress abs(section->VirtualAddress +
244 E : image_file_.nt_headers()->OptionalHeader.ImageBase + i);
245 E : RelativeAddress rel(section->VirtualAddress + i);
246 E : FileOffsetAddress off(section->PointerToRawData + i);
247 E : SectionOffsetAddress sect_off(i + 1, i);
248 :
249 : ASSERT_NO_FATAL_FAILURE(
250 E : TestAddressesAreConsistent(rel, abs, off, sect_off));
251 E : }
252 E : }
253 :
254 E : TEST_F(PEFileTest, TranslateOffImageFails) {
255 : const IMAGE_SECTION_HEADER* section = image_file_.section_header(
256 E : image_file_.nt_headers()->FileHeader.NumberOfSections - 1);
257 :
258 : AbsoluteAddress abs_end(image_file_.nt_headers()->OptionalHeader.ImageBase +
259 E : image_file_.nt_headers()->OptionalHeader.SizeOfImage);
260 E : RelativeAddress rel_end(image_file_.nt_headers()->OptionalHeader.SizeOfImage);
261 E : FileOffsetAddress off_end(section->PointerToRawData + section->SizeOfRawData);
262 :
263 E : AbsoluteAddress abs;
264 E : RelativeAddress rel;
265 E : FileOffsetAddress off;
266 E : ASSERT_FALSE(image_file_.Translate(rel_end, &abs));
267 E : ASSERT_FALSE(image_file_.Translate(abs_end, &rel));
268 E : ASSERT_FALSE(image_file_.Translate(off_end, &rel));
269 E : ASSERT_FALSE(image_file_.Translate(rel_end, &off));
270 E : }
271 :
272 E : TEST_F(PEFileTest, TranslateFileOffsetSpaceNotContiguous) {
273 E : size_t data_index = image_file_.GetSectionIndex(".data");
274 E : ASSERT_NE(kInvalidSection, data_index);
275 :
276 : const IMAGE_SECTION_HEADER* data =
277 E : image_file_.section_header(data_index);
278 E : ASSERT_TRUE(data != NULL);
279 :
280 E : RelativeAddress rel1, rel2;
281 E : rel1.set_value(data->VirtualAddress + data->SizeOfRawData - 1);
282 E : rel2.set_value(data->VirtualAddress + data->SizeOfRawData);
283 :
284 E : FileOffsetAddress off1, off2;
285 E : ASSERT_TRUE(image_file_.Translate(rel1, &off1));
286 E : ASSERT_FALSE(image_file_.Translate(rel2, &off2));
287 :
288 E : RelativeAddress rel3;
289 E : off2 = off1 + 1;
290 E : ASSERT_TRUE(image_file_.Translate(off2, &rel3));
291 E : ASSERT_LT(1, rel3 - rel2);
292 E : }
293 :
294 E : TEST_F(PEFileTest, DecodeRelocs) {
295 E : PEFile::RelocSet relocs;
296 E : ASSERT_TRUE(image_file_.DecodeRelocs(&relocs));
297 :
298 E : PEFile::RelocMap reloc_values;
299 E : ASSERT_TRUE(image_file_.ReadRelocs(relocs, &reloc_values));
300 :
301 : // We expect to have some relocs to validate and we expect that
302 : // all relocation table entries and their corresponding values
303 : // fall within the image's address space
304 E : ASSERT_TRUE(!reloc_values.empty());
305 E : PEFile::RelocMap::const_iterator i = reloc_values.begin();
306 E : for (; i != reloc_values.end(); ++i) {
307 : // Note:
308 : // i->first is a relative pointer yielded by the relocation table
309 : // i->second is the absolute value of that pointer (i.e., the relocation)
310 :
311 E : const RelativeAddress &pointer_location(i->first);
312 :
313 : ASSERT_TRUE(
314 E : image_file_.Contains(pointer_location, sizeof(AbsoluteAddress)));
315 E : }
316 E : }
317 :
318 E : TEST_F(PEFileTest, DecodeExports) {
319 E : PEFile::ExportInfoVector exports;
320 E : ASSERT_TRUE(image_file_.DecodeExports(&exports));
321 :
322 : // This must match the information in the test_dll.def file.
323 : PEFile::ExportInfo expected[] = {
324 : { RelativeAddress(0), "", "", 1 },
325 : { RelativeAddress(0), "BringInOle32DelayLib", "", 2 },
326 : { RelativeAddress(0), "TestExport", "", 3 },
327 : { RelativeAddress(0), "TestUnusedFuncs", "", 4 },
328 : { RelativeAddress(0), "LabelTestFunc", "", 5 },
329 : { RelativeAddress(0), "TestFunctionWithNoPrivateSymbols", "", 6 },
330 : { RelativeAddress(0), "DllMain", "", 7 },
331 : { RelativeAddress(0), "function3", "", 9 },
332 : { RelativeAddress(0), "CreateFileW", "kernel32.CreateFileW", 13 },
333 : { RelativeAddress(0), "function1", "", 17 },
334 : { RelativeAddress(0), "FuncWithOffsetOutOfImage", "", 18 },
335 E : };
336 :
337 E : ASSERT_EQ(ARRAYSIZE(expected), exports.size());
338 :
339 E : const uint8* module_base = reinterpret_cast<const uint8*>(test_dll_);
340 :
341 : // Resolve the exports and compare.
342 E : for (size_t i = 0; i < arraysize(expected); ++i) {
343 E : if (expected[i].forward.empty()) {
344 : // Look up the functions by ordinal.
345 : const uint8* function = reinterpret_cast<const uint8*>(
346 : base::GetFunctionPointerFromNativeLibrary(
347 E : test_dll_, reinterpret_cast<const char*>(expected[i].ordinal)));
348 E : EXPECT_TRUE(function != NULL);
349 :
350 E : expected[i].function = RelativeAddress(function - module_base);
351 : }
352 E : EXPECT_EQ(expected[i].function, exports.at(i).function);
353 E : EXPECT_EQ(expected[i].name, exports.at(i).name);
354 E : EXPECT_EQ(expected[i].forward, exports.at(i).forward);
355 E : EXPECT_EQ(expected[i].ordinal, exports.at(i).ordinal);
356 E : }
357 E : }
358 :
359 E : TEST_F(PEFileTest, DecodeImports) {
360 E : PEFile::ImportDllVector imports;
361 E : ASSERT_TRUE(image_file_.DecodeImports(&imports));
362 :
363 : // Validation the read imports section.
364 : // The test image imports at least kernel32 and the export_dll.
365 E : ASSERT_LE(2U, imports.size());
366 :
367 E : for (size_t i = 0; i < imports.size(); ++i) {
368 E : PEFile::ImportDll& dll = imports[i];
369 : if (0 ==
370 E : base::CompareCaseInsensitiveASCII("export_dll.dll", dll.name.c_str())) {
371 E : ASSERT_EQ(4, dll.functions.size());
372 : // Depending on the optimization settings the order of these elements can
373 : // actually be different.
374 : ASSERT_THAT(dll.functions, testing::WhenSortedBy(
375 : CompareImportInfo(),
376 : testing::ElementsAre(
377 : PEFile::ImportInfo(0, 0, "function1"),
378 : PEFile::ImportInfo(0, 7, ""),
379 : PEFile::ImportInfo(1, 0, "function3"),
380 E : PEFile::ImportInfo(2, 0, "kExportedData"))));
381 : }
382 E : }
383 E : }
384 :
385 E : TEST_F(PEFileTest, DecodeImportsX64) {
386 E : PEFile64::ImportDllVector imports;
387 E : ASSERT_TRUE(image_file_64_.DecodeImports(&imports));
388 :
389 : // Validate the read imports section.
390 : // The test image imports at least kernel32 and user32.
391 E : ASSERT_LE(2U, imports.size());
392 :
393 E : int expected_imports = 0;
394 E : for (size_t i = 0; i < imports.size(); ++i) {
395 E : PEFile64::ImportDll& dll = imports[i];
396 : if (base::CompareCaseInsensitiveASCII("kernel32.dll", dll.name.c_str()) ==
397 : 0 ||
398 : base::CompareCaseInsensitiveASCII("user32.dll", dll.name.c_str()) ==
399 E : 0) {
400 E : expected_imports++;
401 : }
402 E : }
403 :
404 E : EXPECT_EQ(2, expected_imports);
405 E : }
406 :
407 E : TEST_F(PEFileTest, GetSectionIndexByRelativeAddress) {
408 E : size_t num_sections = image_file_.nt_headers()->FileHeader.NumberOfSections;
409 E : for (size_t i = 0; i < num_sections; ++i) {
410 : RelativeAddress section_start(
411 E : image_file_.section_header(i)->VirtualAddress);
412 E : EXPECT_EQ(i, image_file_.GetSectionIndex(section_start, 1));
413 E : }
414 :
415 : RelativeAddress off_end(image_file_.nt_headers()->OptionalHeader.SizeOfImage +
416 E : 0x10000);
417 E : EXPECT_EQ(kInvalidSection, image_file_.GetSectionIndex(off_end, 1));
418 E : }
419 :
420 E : TEST_F(PEFileTest, GetSectionIndexByAbsoluteAddress) {
421 E : size_t image_base = image_file_.nt_headers()->OptionalHeader.ImageBase;
422 E : size_t num_sections = image_file_.nt_headers()->FileHeader.NumberOfSections;
423 E : for (size_t i = 0; i < num_sections; ++i) {
424 : AbsoluteAddress section_start(
425 E : image_file_.section_header(i)->VirtualAddress + image_base);
426 E : EXPECT_EQ(i, image_file_.GetSectionIndex(section_start, 1));
427 E : }
428 :
429 : AbsoluteAddress off_end(image_file_.nt_headers()->OptionalHeader.SizeOfImage +
430 E : 0x10000 + image_base);
431 E : EXPECT_EQ(kInvalidSection, image_file_.GetSectionIndex(off_end, 1));
432 E : }
433 :
434 E : TEST_F(PEFileTest, GetSectionIndexByName) {
435 E : size_t num_sections = image_file_.nt_headers()->FileHeader.NumberOfSections;
436 E : for (size_t i = 0; i < num_sections; ++i) {
437 E : std::string name = image_file_.GetSectionName(i);
438 E : EXPECT_EQ(i, image_file_.GetSectionIndex(name.c_str()));
439 E : }
440 :
441 E : EXPECT_EQ(kInvalidSection, image_file_.GetSectionIndex(".foobar"));
442 E : }
443 :
444 E : TEST_F(PEFileTest, GetSectionHeaderByRelativeAddress) {
445 E : size_t num_sections = image_file_.nt_headers()->FileHeader.NumberOfSections;
446 E : for (size_t i = 0; i < num_sections; ++i) {
447 : RelativeAddress section_start(
448 E : image_file_.section_header(i)->VirtualAddress);
449 : EXPECT_EQ(image_file_.section_header(i),
450 E : image_file_.GetSectionHeader(section_start, 1));
451 E : }
452 :
453 : RelativeAddress off_end(image_file_.nt_headers()->OptionalHeader.SizeOfImage +
454 E : 0x10000);
455 E : EXPECT_EQ(kInvalidSection, image_file_.GetSectionIndex(off_end, 1));
456 E : }
457 :
458 E : TEST_F(PEFileTest, GetSectionHeaderByAbsoluteAddress) {
459 E : size_t image_base = image_file_.nt_headers()->OptionalHeader.ImageBase;
460 E : size_t num_sections = image_file_.nt_headers()->FileHeader.NumberOfSections;
461 E : for (size_t i = 0; i < num_sections; ++i) {
462 : AbsoluteAddress section_start(
463 E : image_file_.section_header(i)->VirtualAddress + image_base);
464 : EXPECT_EQ(image_file_.section_header(i),
465 E : image_file_.GetSectionHeader(section_start, 1));
466 E : }
467 :
468 : AbsoluteAddress off_end(image_file_.nt_headers()->OptionalHeader.SizeOfImage +
469 E : 0x10000 + image_base);
470 E : EXPECT_EQ(kInvalidSection, image_file_.GetSectionIndex(off_end, 1));
471 E : }
472 :
473 E : TEST_F(PEFileTest, GetSectionHeaderByName) {
474 E : size_t num_sections = image_file_.nt_headers()->FileHeader.NumberOfSections;
475 E : for (size_t i = 0; i < num_sections; ++i) {
476 E : std::string name = image_file_.GetSectionName(i);
477 : EXPECT_EQ(image_file_.section_header(i),
478 E : image_file_.GetSectionHeader(name.c_str()));
479 E : }
480 :
481 E : EXPECT_EQ(NULL, image_file_.GetSectionHeader(".foobar"));
482 E : }
483 :
484 E : TEST(PEFileSignatureTest, Serialization) {
485 E : PEFile::Signature sig;
486 E : sig.path = L"C:\foo\bar.dll";
487 E : sig.base_address = AbsoluteAddress(0x1000000);
488 E : sig.module_size = 12345;
489 E : sig.module_time_date_stamp = 9999999;
490 E : sig.module_checksum = 0xbaadf00d;
491 :
492 E : EXPECT_TRUE(testing::TestSerialization(sig));
493 E : }
494 :
495 E : TEST(PEFileSignatureTest, Consistency) {
496 E : PEFile::Signature sig1;
497 E : sig1.path = L"C:\\foo\\bar.dll";
498 E : sig1.base_address = AbsoluteAddress(0x1000000);
499 E : sig1.module_size = 12345;
500 E : sig1.module_time_date_stamp = 9999999;
501 E : sig1.module_checksum = 0xbaadf00d;
502 :
503 : // sig2 is the same, but with a different module path.
504 E : PEFile::Signature sig2(sig1);
505 E : sig2.path = L"C:\\foo\\bar.exe";
506 :
507 E : EXPECT_FALSE(sig1 == sig2);
508 E : EXPECT_TRUE(sig1.IsConsistent(sig2));
509 E : EXPECT_TRUE(sig1.IsConsistentExceptForChecksum(sig2));
510 :
511 E : sig2.module_checksum = sig1.module_checksum + 100;
512 E : EXPECT_FALSE(sig1.IsConsistent(sig2));
513 E : EXPECT_TRUE(sig1.IsConsistentExceptForChecksum(sig2));
514 E : sig2.module_checksum = sig1.module_checksum;
515 :
516 E : sig2.base_address = sig1.base_address + 0x1000;
517 E : EXPECT_FALSE(sig1.IsConsistent(sig2));
518 E : EXPECT_FALSE(sig1.IsConsistentExceptForChecksum(sig2));
519 E : sig2.base_address = sig1.base_address;
520 :
521 E : sig2.module_size = sig2.module_size + 0x1000;
522 E : EXPECT_FALSE(sig1.IsConsistent(sig2));
523 E : EXPECT_FALSE(sig1.IsConsistentExceptForChecksum(sig2));
524 E : }
525 :
526 : } // namespace pe
|