OLD | NEW |
| (Empty) |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 // This file contains unit tests for PEImage. | |
6 | |
7 #include "testing/gtest/include/gtest/gtest.h" | |
8 #include "base/pe_image.h" | |
9 #include "base/win/windows_version.h" | |
10 | |
11 // Just counts the number of invocations. | |
12 bool ExportsCallback(const PEImage &image, | |
13 DWORD ordinal, | |
14 DWORD hint, | |
15 LPCSTR name, | |
16 PVOID function, | |
17 LPCSTR forward, | |
18 PVOID cookie) { | |
19 int* count = reinterpret_cast<int*>(cookie); | |
20 (*count)++; | |
21 return true; | |
22 } | |
23 | |
24 // Just counts the number of invocations. | |
25 bool ImportsCallback(const PEImage &image, | |
26 LPCSTR module, | |
27 DWORD ordinal, | |
28 LPCSTR name, | |
29 DWORD hint, | |
30 PIMAGE_THUNK_DATA iat, | |
31 PVOID cookie) { | |
32 int* count = reinterpret_cast<int*>(cookie); | |
33 (*count)++; | |
34 return true; | |
35 } | |
36 | |
37 // Just counts the number of invocations. | |
38 bool SectionsCallback(const PEImage &image, | |
39 PIMAGE_SECTION_HEADER header, | |
40 PVOID section_start, | |
41 DWORD section_size, | |
42 PVOID cookie) { | |
43 int* count = reinterpret_cast<int*>(cookie); | |
44 (*count)++; | |
45 return true; | |
46 } | |
47 | |
48 // Just counts the number of invocations. | |
49 bool RelocsCallback(const PEImage &image, | |
50 WORD type, | |
51 PVOID address, | |
52 PVOID cookie) { | |
53 int* count = reinterpret_cast<int*>(cookie); | |
54 (*count)++; | |
55 return true; | |
56 } | |
57 | |
58 // Just counts the number of invocations. | |
59 bool ImportChunksCallback(const PEImage &image, | |
60 LPCSTR module, | |
61 PIMAGE_THUNK_DATA name_table, | |
62 PIMAGE_THUNK_DATA iat, | |
63 PVOID cookie) { | |
64 int* count = reinterpret_cast<int*>(cookie); | |
65 (*count)++; | |
66 return true; | |
67 } | |
68 | |
69 // Just counts the number of invocations. | |
70 bool DelayImportChunksCallback(const PEImage &image, | |
71 PImgDelayDescr delay_descriptor, | |
72 LPCSTR module, | |
73 PIMAGE_THUNK_DATA name_table, | |
74 PIMAGE_THUNK_DATA iat, | |
75 PIMAGE_THUNK_DATA bound_iat, | |
76 PIMAGE_THUNK_DATA unload_iat, | |
77 PVOID cookie) { | |
78 int* count = reinterpret_cast<int*>(cookie); | |
79 (*count)++; | |
80 return true; | |
81 } | |
82 | |
83 // We'll be using some known values for the tests. | |
84 enum Value { | |
85 sections = 0, | |
86 imports_dlls, | |
87 delay_dlls, | |
88 exports, | |
89 imports, | |
90 delay_imports, | |
91 relocs | |
92 }; | |
93 | |
94 // Retrieves the expected value from advapi32.dll based on the OS. | |
95 int GetExpectedValue(Value value, DWORD os) { | |
96 const int xp_delay_dlls = 2; | |
97 const int xp_exports = 675; | |
98 const int xp_imports = 422; | |
99 const int xp_delay_imports = 8; | |
100 const int xp_relocs = 9180; | |
101 const int vista_delay_dlls = 4; | |
102 const int vista_exports = 799; | |
103 const int vista_imports = 476; | |
104 const int vista_delay_imports = 24; | |
105 const int vista_relocs = 10188; | |
106 const int w2k_delay_dlls = 0; | |
107 const int w2k_exports = 566; | |
108 const int w2k_imports = 357; | |
109 const int w2k_delay_imports = 0; | |
110 const int w2k_relocs = 7388; | |
111 const int win7_delay_dlls = 7; | |
112 const int win7_exports = 806; | |
113 const int win7_imports = 568; | |
114 const int win7_delay_imports = 71; | |
115 const int win7_relocs = 7812; | |
116 | |
117 // Contains the expected value, for each enumerated property (Value), and the | |
118 // OS version: [Value][os_version] | |
119 const int expected[][4] = { | |
120 {4, 4, 4, 4}, | |
121 {3, 3, 3, 13}, | |
122 {w2k_delay_dlls, xp_delay_dlls, vista_delay_dlls, win7_delay_dlls}, | |
123 {w2k_exports, xp_exports, vista_exports, win7_exports}, | |
124 {w2k_imports, xp_imports, vista_imports, win7_imports}, | |
125 {w2k_delay_imports, xp_delay_imports, | |
126 vista_delay_imports, win7_delay_imports}, | |
127 {w2k_relocs, xp_relocs, vista_relocs, win7_relocs} | |
128 }; | |
129 | |
130 if (value > relocs) | |
131 return 0; | |
132 if (50 == os) | |
133 os = 0; // 5.0 | |
134 else if (51 == os || 52 == os) | |
135 os = 1; | |
136 else if (os == 60) | |
137 os = 2; // 6.x | |
138 else if (os >= 61) | |
139 os = 3; | |
140 else | |
141 return 0; | |
142 | |
143 return expected[value][os]; | |
144 } | |
145 | |
146 // Tests that we are able to enumerate stuff from a PE file, and that | |
147 // the actual number of items found is within the expected range. | |
148 TEST(PEImageTest, EnumeratesPE) { | |
149 // Windows Server 2003 is not supported as a test environment for this test. | |
150 if (base::win::GetVersion() == base::win::VERSION_SERVER_2003) | |
151 return; | |
152 HMODULE module = LoadLibrary(L"advapi32.dll"); | |
153 ASSERT_TRUE(NULL != module); | |
154 | |
155 PEImage pe(module); | |
156 int count = 0; | |
157 EXPECT_TRUE(pe.VerifyMagic()); | |
158 | |
159 DWORD os = pe.GetNTHeaders()->OptionalHeader.MajorOperatingSystemVersion; | |
160 os = os * 10 + pe.GetNTHeaders()->OptionalHeader.MinorOperatingSystemVersion; | |
161 | |
162 pe.EnumSections(SectionsCallback, &count); | |
163 EXPECT_EQ(GetExpectedValue(sections, os), count); | |
164 | |
165 count = 0; | |
166 pe.EnumImportChunks(ImportChunksCallback, &count); | |
167 EXPECT_EQ(GetExpectedValue(imports_dlls, os), count); | |
168 | |
169 count = 0; | |
170 pe.EnumDelayImportChunks(DelayImportChunksCallback, &count); | |
171 EXPECT_EQ(GetExpectedValue(delay_dlls, os), count); | |
172 | |
173 count = 0; | |
174 pe.EnumExports(ExportsCallback, &count); | |
175 EXPECT_GT(count, GetExpectedValue(exports, os) - 20); | |
176 EXPECT_LT(count, GetExpectedValue(exports, os) + 100); | |
177 | |
178 count = 0; | |
179 pe.EnumAllImports(ImportsCallback, &count); | |
180 EXPECT_GT(count, GetExpectedValue(imports, os) - 20); | |
181 EXPECT_LT(count, GetExpectedValue(imports, os) + 100); | |
182 | |
183 count = 0; | |
184 pe.EnumAllDelayImports(ImportsCallback, &count); | |
185 EXPECT_GT(count, GetExpectedValue(delay_imports, os) - 2); | |
186 EXPECT_LT(count, GetExpectedValue(delay_imports, os) + 8); | |
187 | |
188 count = 0; | |
189 pe.EnumRelocs(RelocsCallback, &count); | |
190 EXPECT_GT(count, GetExpectedValue(relocs, os) - 150); | |
191 EXPECT_LT(count, GetExpectedValue(relocs, os) + 1500); | |
192 | |
193 FreeLibrary(module); | |
194 } | |
195 | |
196 // Tests that we can locate an specific exported symbol, by name and by ordinal. | |
197 TEST(PEImageTest, RetrievesExports) { | |
198 HMODULE module = LoadLibrary(L"advapi32.dll"); | |
199 ASSERT_TRUE(NULL != module); | |
200 | |
201 PEImage pe(module); | |
202 WORD ordinal; | |
203 | |
204 EXPECT_TRUE(pe.GetProcOrdinal("RegEnumKeyExW", &ordinal)); | |
205 | |
206 FARPROC address1 = pe.GetProcAddress("RegEnumKeyExW"); | |
207 FARPROC address2 = pe.GetProcAddress(reinterpret_cast<char*>(ordinal)); | |
208 EXPECT_TRUE(address1 != NULL); | |
209 EXPECT_TRUE(address2 != NULL); | |
210 EXPECT_TRUE(address1 == address2); | |
211 | |
212 FreeLibrary(module); | |
213 } | |
OLD | NEW |