| 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 |