OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // This file contains unit tests for PEImage. | 5 // This file contains unit tests for PEImage. |
6 #include <algorithm> | 6 #include <algorithm> |
7 #include <vector> | 7 #include <vector> |
8 | 8 |
| 9 #include "base/files/file_path.h" |
| 10 #include "base/path_service.h" |
| 11 #include "base/win/pe_image.h" |
9 #include "testing/gtest/include/gtest/gtest.h" | 12 #include "testing/gtest/include/gtest/gtest.h" |
10 #include "base/win/pe_image.h" | |
11 #include "base/win/windows_version.h" | |
12 | |
13 namespace { | |
14 | |
15 class Expectations { | |
16 public: | |
17 enum Value { | |
18 SECTIONS = 0, | |
19 IMPORTS_DLLS, | |
20 DELAY_DLLS, | |
21 EXPORTS, | |
22 IMPORTS, | |
23 DELAY_IMPORTS, | |
24 RELOCS | |
25 }; | |
26 | |
27 enum Arch { | |
28 ARCH_X86 = 0, | |
29 ARCH_X64, | |
30 ARCH_ALL | |
31 }; | |
32 | |
33 Expectations(); | |
34 | |
35 void SetDefault(Value value, int count); | |
36 void SetOverride(Value value, base::win::Version version, | |
37 Arch arch, int count); | |
38 void SetOverride(Value value, base::win::Version version, int count); | |
39 void SetOverride(Value value, Arch arch, int count); | |
40 | |
41 // returns -1 on failure. | |
42 int GetExpectation(Value value); | |
43 | |
44 private: | |
45 class Override { | |
46 public: | |
47 enum MatchType { MATCH_VERSION, MATCH_ARCH, MATCH_BOTH, MATCH_NONE }; | |
48 | |
49 Override(Value value, base::win::Version version, Arch arch, int count) | |
50 : value_(value), version_(version), arch_(arch), count_(count) { | |
51 }; | |
52 | |
53 bool Matches(Value value, base::win::Version version, | |
54 Arch arch, MatchType type) { | |
55 if (value_ != value) | |
56 return false; | |
57 | |
58 switch (type) { | |
59 case MATCH_BOTH: | |
60 return (arch == arch_ && version == version_); | |
61 case MATCH_ARCH: | |
62 return (arch == arch_ && version_ == base::win::VERSION_WIN_LAST); | |
63 case MATCH_VERSION: | |
64 return (arch_ == ARCH_ALL && version == version_); | |
65 case MATCH_NONE: | |
66 return (arch_ == ARCH_ALL && version_ == base::win::VERSION_WIN_LAST); | |
67 } | |
68 return false; | |
69 } | |
70 | |
71 int GetCount() { return count_; } | |
72 | |
73 private: | |
74 Value value_; | |
75 base::win::Version version_; | |
76 Arch arch_; | |
77 int count_; | |
78 }; | |
79 | |
80 bool MatchesMyArch(Arch arch); | |
81 | |
82 std::vector<Override> overrides_; | |
83 Arch my_arch_; | |
84 base::win::Version my_version_; | |
85 }; | |
86 | |
87 Expectations::Expectations() { | |
88 my_version_ = base::win::GetVersion(); | |
89 #if defined(ARCH_CPU_64_BITS) | |
90 my_arch_ = ARCH_X64; | |
91 #else | |
92 my_arch_ = ARCH_X86; | |
93 #endif | |
94 } | |
95 | |
96 int Expectations::GetExpectation(Value value) { | |
97 // Prefer OS version specificity over Arch specificity. | |
98 for (auto type : { Override::MATCH_BOTH, | |
99 Override::MATCH_VERSION, | |
100 Override::MATCH_ARCH, | |
101 Override::MATCH_NONE }) { | |
102 for (auto override : overrides_) { | |
103 if (override.Matches(value, my_version_, my_arch_, type)) | |
104 return override.GetCount(); | |
105 } | |
106 } | |
107 return -1; | |
108 } | |
109 | |
110 void Expectations::SetDefault(Value value, int count) { | |
111 SetOverride(value, base::win::VERSION_WIN_LAST, ARCH_ALL, count); | |
112 } | |
113 | |
114 void Expectations::SetOverride(Value value, | |
115 base::win::Version version, | |
116 Arch arch, | |
117 int count) { | |
118 overrides_.push_back(Override(value, version, arch, count)); | |
119 } | |
120 | |
121 void Expectations::SetOverride(Value value, | |
122 base::win::Version version, | |
123 int count) { | |
124 SetOverride(value, version, ARCH_ALL, count); | |
125 } | |
126 | |
127 void Expectations::SetOverride(Value value, Arch arch, int count) { | |
128 SetOverride(value, base::win::VERSION_WIN_LAST, arch, count); | |
129 } | |
130 | |
131 } // namespace | |
132 | 13 |
133 namespace base { | 14 namespace base { |
134 namespace win { | 15 namespace win { |
135 | 16 |
136 namespace { | 17 namespace { |
137 | 18 |
138 // Just counts the number of invocations. | 19 // Just counts the number of invocations. |
139 bool ImportsCallback(const PEImage& image, | 20 bool ImportsCallback(const PEImage& image, |
140 LPCSTR module, | 21 LPCSTR module, |
141 DWORD ordinal, | 22 DWORD ordinal, |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
203 LPCSTR forward, | 84 LPCSTR forward, |
204 PVOID cookie) { | 85 PVOID cookie) { |
205 int* count = reinterpret_cast<int*>(cookie); | 86 int* count = reinterpret_cast<int*>(cookie); |
206 (*count)++; | 87 (*count)++; |
207 return true; | 88 return true; |
208 } | 89 } |
209 | 90 |
210 } // namespace | 91 } // namespace |
211 | 92 |
212 // Tests that we are able to enumerate stuff from a PE file, and that | 93 // Tests that we are able to enumerate stuff from a PE file, and that |
213 // the actual number of items found is within the expected range. | 94 // the actual number of items found matches an expected value. |
214 TEST(PEImageTest, EnumeratesPE) { | 95 TEST(PEImageTest, EnumeratesPE) { |
215 Expectations expectations; | 96 base::FilePath pe_image_test_path; |
| 97 ASSERT_TRUE(PathService::Get(DIR_TEST_DATA, &pe_image_test_path)); |
| 98 pe_image_test_path = pe_image_test_path.Append(FILE_PATH_LITERAL("pe_image")); |
216 | 99 |
217 #ifndef NDEBUG | 100 #if defined(ARCH_CPU_64_BITS) |
218 // Default Debug expectations. | 101 pe_image_test_path = |
219 expectations.SetDefault(Expectations::SECTIONS, 7); | 102 pe_image_test_path.Append(FILE_PATH_LITERAL("pe_image_test_64.dll")); |
220 expectations.SetDefault(Expectations::IMPORTS_DLLS, 3); | 103 const int sections = 6; |
221 expectations.SetDefault(Expectations::DELAY_DLLS, 2); | 104 const int imports_dlls = 2; |
222 expectations.SetDefault(Expectations::EXPORTS, 2); | 105 const int delay_dlls = 2; |
223 expectations.SetDefault(Expectations::IMPORTS, 49); | 106 const int exports = 2; |
224 expectations.SetDefault(Expectations::DELAY_IMPORTS, 2); | 107 const int imports = 69; |
225 expectations.SetDefault(Expectations::RELOCS, 438); | 108 const int delay_imports = 2; |
226 | 109 const int relocs = 632; |
227 // 64-bit Debug expectations. | |
228 expectations.SetOverride(Expectations::SECTIONS, Expectations::ARCH_X64, 8); | |
229 expectations.SetOverride(Expectations::IMPORTS, Expectations::ARCH_X64, 69); | |
230 expectations.SetOverride(Expectations::RELOCS, Expectations::ARCH_X64, 632); | |
231 #else | 110 #else |
232 // Default Release expectations. | 111 pe_image_test_path = |
233 expectations.SetDefault(Expectations::SECTIONS, 5); | 112 pe_image_test_path.Append(FILE_PATH_LITERAL("pe_image_test_32.dll")); |
234 expectations.SetDefault(Expectations::IMPORTS_DLLS, 2); | 113 const int sections = 5; |
235 expectations.SetDefault(Expectations::DELAY_DLLS, 2); | 114 const int imports_dlls = 2; |
236 expectations.SetDefault(Expectations::EXPORTS, 2); | 115 const int delay_dlls = 2; |
237 expectations.SetDefault(Expectations::IMPORTS, 66); | 116 const int exports = 2; |
238 expectations.SetDefault(Expectations::DELAY_IMPORTS, 2); | 117 const int imports = 66; |
239 expectations.SetDefault(Expectations::RELOCS, 1586); | 118 const int delay_imports = 2; |
240 | 119 const int relocs = 1586; |
241 // 64-bit Release expectations. | |
242 expectations.SetOverride(Expectations::SECTIONS, Expectations::ARCH_X64, 6); | |
243 expectations.SetOverride(Expectations::IMPORTS, Expectations::ARCH_X64, 69); | |
244 expectations.SetOverride(Expectations::RELOCS, Expectations::ARCH_X64, 632); | |
245 #endif | 120 #endif |
246 | 121 |
247 HMODULE module = LoadLibrary(L"pe_image_test.dll"); | 122 HMODULE module = LoadLibrary(pe_image_test_path.value().c_str()); |
248 ASSERT_TRUE(NULL != module); | 123 ASSERT_TRUE(NULL != module); |
249 | 124 |
250 PEImage pe(module); | 125 PEImage pe(module); |
251 int count = 0; | 126 int count = 0; |
252 EXPECT_TRUE(pe.VerifyMagic()); | 127 EXPECT_TRUE(pe.VerifyMagic()); |
253 | 128 |
254 pe.EnumSections(SectionsCallback, &count); | 129 pe.EnumSections(SectionsCallback, &count); |
255 EXPECT_EQ(expectations.GetExpectation(Expectations::SECTIONS), count); | 130 EXPECT_EQ(sections, count); |
256 | 131 |
257 count = 0; | 132 count = 0; |
258 pe.EnumImportChunks(ImportChunksCallback, &count); | 133 pe.EnumImportChunks(ImportChunksCallback, &count); |
259 EXPECT_EQ(expectations.GetExpectation(Expectations::IMPORTS_DLLS), count); | 134 EXPECT_EQ(imports_dlls, count); |
260 | 135 |
261 count = 0; | 136 count = 0; |
262 pe.EnumDelayImportChunks(DelayImportChunksCallback, &count); | 137 pe.EnumDelayImportChunks(DelayImportChunksCallback, &count); |
263 EXPECT_EQ(expectations.GetExpectation(Expectations::DELAY_DLLS), count); | 138 EXPECT_EQ(delay_dlls, count); |
264 | 139 |
265 count = 0; | 140 count = 0; |
266 pe.EnumExports(ExportsCallback, &count); | 141 pe.EnumExports(ExportsCallback, &count); |
267 EXPECT_EQ(expectations.GetExpectation(Expectations::EXPORTS), count); | 142 EXPECT_EQ(exports, count); |
268 | 143 |
269 count = 0; | 144 count = 0; |
270 pe.EnumAllImports(ImportsCallback, &count); | 145 pe.EnumAllImports(ImportsCallback, &count); |
271 EXPECT_EQ(expectations.GetExpectation(Expectations::IMPORTS), count); | 146 EXPECT_EQ(imports, count); |
272 | 147 |
273 count = 0; | 148 count = 0; |
274 pe.EnumAllDelayImports(ImportsCallback, &count); | 149 pe.EnumAllDelayImports(ImportsCallback, &count); |
275 EXPECT_EQ(expectations.GetExpectation(Expectations::DELAY_IMPORTS), count); | 150 EXPECT_EQ(delay_imports, count); |
276 | 151 |
277 count = 0; | 152 count = 0; |
278 pe.EnumRelocs(RelocsCallback, &count); | 153 pe.EnumRelocs(RelocsCallback, &count); |
279 EXPECT_EQ(expectations.GetExpectation(Expectations::RELOCS), count); | 154 EXPECT_EQ(relocs, count); |
280 | 155 |
281 FreeLibrary(module); | 156 FreeLibrary(module); |
282 } | 157 } |
283 | 158 |
284 // Tests that we can locate an specific exported symbol, by name and by ordinal. | 159 // Tests that we can locate an specific exported symbol, by name and by ordinal. |
285 TEST(PEImageTest, RetrievesExports) { | 160 TEST(PEImageTest, RetrievesExports) { |
286 HMODULE module = LoadLibrary(L"advapi32.dll"); | 161 HMODULE module = LoadLibrary(L"advapi32.dll"); |
287 ASSERT_TRUE(NULL != module); | 162 ASSERT_TRUE(NULL != module); |
288 | 163 |
289 PEImage pe(module); | 164 PEImage pe(module); |
(...skipping 21 matching lines...) Expand all Loading... |
311 EXPECT_TRUE(pe.GetDebugId(&guid, &age)); | 186 EXPECT_TRUE(pe.GetDebugId(&guid, &age)); |
312 | 187 |
313 GUID empty_guid = {0}; | 188 GUID empty_guid = {0}; |
314 EXPECT_TRUE(!IsEqualGUID(empty_guid, guid)); | 189 EXPECT_TRUE(!IsEqualGUID(empty_guid, guid)); |
315 EXPECT_NE(0U, age); | 190 EXPECT_NE(0U, age); |
316 FreeLibrary(module); | 191 FreeLibrary(module); |
317 } | 192 } |
318 | 193 |
319 } // namespace win | 194 } // namespace win |
320 } // namespace base | 195 } // namespace base |
OLD | NEW |