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
3 // found in the LICENSE file.
5 // This file contains unit tests for PEImage.
7 #include "testing/gtest/include/gtest/gtest.h"
8 #include "base/win/pe_image.h"
9 #include "base/win/windows_version.h"
14 // Just counts the number of invocations.
15 bool ExportsCallback(const PEImage
&image
,
22 int* count
= reinterpret_cast<int*>(cookie
);
27 // Just counts the number of invocations.
28 bool ImportsCallback(const PEImage
&image
,
33 PIMAGE_THUNK_DATA iat
,
35 int* count
= reinterpret_cast<int*>(cookie
);
40 // Just counts the number of invocations.
41 bool SectionsCallback(const PEImage
&image
,
42 PIMAGE_SECTION_HEADER header
,
46 int* count
= reinterpret_cast<int*>(cookie
);
51 // Just counts the number of invocations.
52 bool RelocsCallback(const PEImage
&image
,
56 int* count
= reinterpret_cast<int*>(cookie
);
61 // Just counts the number of invocations.
62 bool ImportChunksCallback(const PEImage
&image
,
64 PIMAGE_THUNK_DATA name_table
,
65 PIMAGE_THUNK_DATA iat
,
67 int* count
= reinterpret_cast<int*>(cookie
);
72 // Just counts the number of invocations.
73 bool DelayImportChunksCallback(const PEImage
&image
,
74 PImgDelayDescr delay_descriptor
,
76 PIMAGE_THUNK_DATA name_table
,
77 PIMAGE_THUNK_DATA iat
,
78 PIMAGE_THUNK_DATA bound_iat
,
79 PIMAGE_THUNK_DATA unload_iat
,
81 int* count
= reinterpret_cast<int*>(cookie
);
86 // Identifiers for the set of supported expectations.
96 // We'll be using some known values for the tests.
107 ExpectationSet
GetExpectationSet(DWORD os
) {
113 return WIN_VISTA_SET
;
118 return UNSUPPORTED_SET
;
121 // Retrieves the expected value from advapi32.dll based on the OS.
122 int GetExpectedValue(Value value
, DWORD os
) {
123 const int xp_delay_dlls
= 2;
124 const int xp_exports
= 675;
125 const int xp_imports
= 422;
126 const int xp_delay_imports
= 8;
127 const int xp_relocs
= 9180;
128 const int vista_delay_dlls
= 4;
129 const int vista_exports
= 799;
130 const int vista_imports
= 476;
131 const int vista_delay_imports
= 24;
132 const int vista_relocs
= 10188;
133 const int w2k_delay_dlls
= 0;
134 const int w2k_exports
= 566;
135 const int w2k_imports
= 357;
136 const int w2k_delay_imports
= 0;
137 const int w2k_relocs
= 7388;
138 const int win7_delay_dlls
= 7;
139 const int win7_exports
= 806;
140 const int win7_imports
= 568;
141 const int win7_delay_imports
= 71;
142 int win7_relocs
= 7812;
143 int win7_sections
= 4;
144 const int win8_delay_dlls
= 9;
145 const int win8_exports
= 806;
146 const int win8_imports
= 568;
147 const int win8_delay_imports
= 113;
148 const int win8_relocs
= 9478;
149 int win8_sections
= 4;
150 int win8_import_dlls
= 17;
152 base::win::OSInfo
* os_info
= base::win::OSInfo::GetInstance();
153 // 32-bit process on a 32-bit system.
154 if (os_info
->architecture() == base::win::OSInfo::X86_ARCHITECTURE
) {
156 win8_import_dlls
= 19;
158 // 64-bit process on a 64-bit system.
159 } else if (os_info
->wow64_status() == base::win::OSInfo::WOW64_DISABLED
) {
164 // Contains the expected value, for each enumerated property (Value), and the
165 // OS version: [Value][os_version]
166 const int expected
[][5] = {
167 {4, 4, 4, win7_sections
, win8_sections
},
168 {3, 3, 3, 13, win8_import_dlls
},
169 {w2k_delay_dlls
, xp_delay_dlls
, vista_delay_dlls
, win7_delay_dlls
,
171 {w2k_exports
, xp_exports
, vista_exports
, win7_exports
, win8_exports
},
172 {w2k_imports
, xp_imports
, vista_imports
, win7_imports
, win8_imports
},
173 {w2k_delay_imports
, xp_delay_imports
,
174 vista_delay_imports
, win7_delay_imports
, win8_delay_imports
},
175 {w2k_relocs
, xp_relocs
, vista_relocs
, win7_relocs
, win8_relocs
}
177 COMPILE_ASSERT(arraysize(expected
[0]) == UNSUPPORTED_SET
,
178 expected_value_set_mismatch
);
182 ExpectationSet expected_set
= GetExpectationSet(os
);
183 if (expected_set
>= arraysize(expected
)) {
184 // This should never happen. Log a failure if it does.
185 EXPECT_NE(UNSUPPORTED_SET
, expected_set
);
186 expected_set
= WIN_2K_SET
;
189 return expected
[value
][expected_set
];
193 // TODO(jschuh): crbug.com/167707 Need to fix test on Win64 bots
194 #if defined(OS_WIN) && defined(ARCH_CPU_X86_64)
195 #define MAYBE_EnumeratesPE DISABLED_EnumeratesPE
197 #define MAYBE_EnumeratesPE EnumeratesPE
200 // Tests that we are able to enumerate stuff from a PE file, and that
201 // the actual number of items found is within the expected range.
202 TEST(PEImageTest
, MAYBE_EnumeratesPE
) {
203 HMODULE module
= LoadLibrary(L
"advapi32.dll");
204 ASSERT_TRUE(NULL
!= module
);
208 EXPECT_TRUE(pe
.VerifyMagic());
210 DWORD os
= pe
.GetNTHeaders()->OptionalHeader
.MajorOperatingSystemVersion
;
211 os
= os
* 10 + pe
.GetNTHeaders()->OptionalHeader
.MinorOperatingSystemVersion
;
213 // Skip this test for unsupported OS versions.
214 if (GetExpectationSet(os
) == UNSUPPORTED_SET
)
217 pe
.EnumSections(SectionsCallback
, &count
);
218 EXPECT_EQ(GetExpectedValue(sections
, os
), count
);
221 pe
.EnumImportChunks(ImportChunksCallback
, &count
);
222 EXPECT_EQ(GetExpectedValue(imports_dlls
, os
), count
);
225 pe
.EnumDelayImportChunks(DelayImportChunksCallback
, &count
);
226 EXPECT_EQ(GetExpectedValue(delay_dlls
, os
), count
);
229 pe
.EnumExports(ExportsCallback
, &count
);
230 EXPECT_GT(count
, GetExpectedValue(exports
, os
) - 20);
231 EXPECT_LT(count
, GetExpectedValue(exports
, os
) + 100);
234 pe
.EnumAllImports(ImportsCallback
, &count
);
235 EXPECT_GT(count
, GetExpectedValue(imports
, os
) - 20);
236 EXPECT_LT(count
, GetExpectedValue(imports
, os
) + 100);
239 pe
.EnumAllDelayImports(ImportsCallback
, &count
);
240 EXPECT_GT(count
, GetExpectedValue(delay_imports
, os
) - 2);
241 EXPECT_LT(count
, GetExpectedValue(delay_imports
, os
) + 8);
244 pe
.EnumRelocs(RelocsCallback
, &count
);
245 EXPECT_GT(count
, GetExpectedValue(relocs
, os
) - 150);
246 EXPECT_LT(count
, GetExpectedValue(relocs
, os
) + 1500);
251 // Tests that we can locate an specific exported symbol, by name and by ordinal.
252 TEST(PEImageTest
, RetrievesExports
) {
253 HMODULE module
= LoadLibrary(L
"advapi32.dll");
254 ASSERT_TRUE(NULL
!= module
);
259 EXPECT_TRUE(pe
.GetProcOrdinal("RegEnumKeyExW", &ordinal
));
261 FARPROC address1
= pe
.GetProcAddress("RegEnumKeyExW");
262 FARPROC address2
= pe
.GetProcAddress(reinterpret_cast<char*>(ordinal
));
263 EXPECT_TRUE(address1
!= NULL
);
264 EXPECT_TRUE(address2
!= NULL
);
265 EXPECT_TRUE(address1
== address2
);