blob: 2bfa0629ffc861a4e9513a4c60409e980964ff8b [file] [log] [blame]
license.botbf09a502008-08-24 00:55:551// 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.
initial.commitd7cae122008-07-26 21:49:384
5// This file contains unit tests for PEImage.
6
7#include "testing/gtest/include/gtest/gtest.h"
8#include "base/pe_image.h"
[email protected]b6545a452008-09-29 19:54:519#include "base/win_util.h"
initial.commitd7cae122008-07-26 21:49:3810
11// Just counts the number of invocations.
12bool 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.
25bool 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.
38bool 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.
49bool 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.
59bool 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.
70bool 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.
84enum 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.
95int 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
112 // Contains the expected value, for each enumerated property (Value), and the
113 // OS version: [Value][os_version]
114 const int expected[][3] = {
115 {4, 4, 4},
116 {3, 3, 3},
117 {w2k_delay_dlls, xp_delay_dlls, vista_delay_dlls},
118 {w2k_exports, xp_exports, vista_exports},
119 {w2k_imports, xp_imports, vista_imports},
120 {w2k_delay_imports, xp_delay_imports, vista_delay_imports},
121 {w2k_relocs, xp_relocs, vista_relocs}
122 };
123
124 if (value > relocs)
125 return 0;
126 if (50 == os)
127 os = 0; // 5.0
128 else if (51 == os || 52 == os)
129 os = 1;
130 else if (os >= 60)
131 os = 2; // 6.x
132 else
133 return 0;
134
135 return expected[value][os];
136}
137
138// Tests that we are able to enumerate stuff from a PE file, and that
139// the actual number of items found is within the expected range.
140TEST(PEImageTest, EnumeratesPE) {
[email protected]b6545a452008-09-29 19:54:51141 // Windows Server 2003 is not supported as a test environment for this test.
142 if (win_util::GetWinVersion() == win_util::WINVERSION_SERVER_2003)
143 return;
initial.commitd7cae122008-07-26 21:49:38144 HMODULE module = LoadLibrary(L"advapi32.dll");
145 ASSERT_TRUE(NULL != module);
146
147 PEImage pe(module);
148 int count = 0;
149 EXPECT_TRUE(pe.VerifyMagic());
150
151 DWORD os = pe.GetNTHeaders()->OptionalHeader.MajorOperatingSystemVersion;
152 os = os * 10 + pe.GetNTHeaders()->OptionalHeader.MinorOperatingSystemVersion;
153
154 pe.EnumSections(SectionsCallback, &count);
155 EXPECT_EQ(GetExpectedValue(sections, os), count);
156
157 count = 0;
158 pe.EnumImportChunks(ImportChunksCallback, &count);
159 EXPECT_EQ(GetExpectedValue(imports_dlls, os), count);
160
161 count = 0;
162 pe.EnumDelayImportChunks(DelayImportChunksCallback, &count);
163 EXPECT_EQ(GetExpectedValue(delay_dlls, os), count);
164
165 count = 0;
166 pe.EnumExports(ExportsCallback, &count);
167 EXPECT_GT(count, GetExpectedValue(exports, os) - 20);
168 EXPECT_LT(count, GetExpectedValue(exports, os) + 100);
169
170 count = 0;
171 pe.EnumAllImports(ImportsCallback, &count);
172 EXPECT_GT(count, GetExpectedValue(imports, os) - 20);
173 EXPECT_LT(count, GetExpectedValue(imports, os) + 100);
174
175 count = 0;
176 pe.EnumAllDelayImports(ImportsCallback, &count);
177 EXPECT_GT(count, GetExpectedValue(delay_imports, os) - 2);
178 EXPECT_LT(count, GetExpectedValue(delay_imports, os) + 8);
179
180 count = 0;
181 pe.EnumRelocs(RelocsCallback, &count);
182 EXPECT_GT(count, GetExpectedValue(relocs, os) - 150);
183 EXPECT_LT(count, GetExpectedValue(relocs, os) + 1500);
184
185 FreeLibrary(module);
186}
187
188// Tests that we can locate an specific exported symbol, by name and by ordinal.
189TEST(PEImageTest, RetrievesExports) {
190 HMODULE module = LoadLibrary(L"advapi32.dll");
191 ASSERT_TRUE(NULL != module);
192
193 PEImage pe(module);
194 WORD ordinal;
195
196 EXPECT_TRUE(pe.GetProcOrdinal("RegEnumKeyExW", &ordinal));
197
198 FARPROC address1 = pe.GetProcAddress("RegEnumKeyExW");
199 FARPROC address2 = pe.GetProcAddress(reinterpret_cast<char*>(ordinal));
200 EXPECT_TRUE(address1 != NULL);
201 EXPECT_TRUE(address2 != NULL);
202 EXPECT_TRUE(address1 == address2);
203
204 FreeLibrary(module);
205}