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