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