blob: 4d47356282d42218843b10131bcdeece6ee1082f [file] [log] [blame]
license.botf003cfe2008-08-24 09:55:55 +09001// 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.commit3f4a7322008-07-27 06:49:38 +09004
5// This file contains unit tests for PEImage.
6
7#include "testing/gtest/include/gtest/gtest.h"
8#include "base/pe_image.h"
9
10// Just counts the number of invocations.
11bool ExportsCallback(const 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.
24bool ImportsCallback(const 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.
37bool SectionsCallback(const 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.
48bool RelocsCallback(const 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.
58bool ImportChunksCallback(const 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.
69bool DelayImportChunksCallback(const 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.
83enum 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.
94int 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.
139TEST(PEImageTest, EnumeratesPE) {
140 HMODULE module = LoadLibrary(L"advapi32.dll");
141 ASSERT_TRUE(NULL != module);
142
143 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.
185TEST(PEImageTest, RetrievesExports) {
186 HMODULE module = LoadLibrary(L"advapi32.dll");
187 ASSERT_TRUE(NULL != module);
188
189 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}
license.botf003cfe2008-08-24 09:55:55 +0900202