1 // Copyright 2014 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 #include <stdint.h> 6 #include <windows.h> 7 8 #include <algorithm> 9 #include <vector> 10 11 #include "base/base_paths.h" 12 #include "base/basictypes.h" 13 #include "base/compiler_specific.h" 14 #include "base/files/file_path.h" 15 #include "base/files/memory_mapped_file.h" 16 #include "base/path_service.h" 17 #include "base/strings/string_util.h" 18 #include "base/win/pe_image.h" 19 #include "testing/gtest/include/gtest/gtest.h" 20 21 namespace { 22 23 class ELFImportsTest : public testing::Test { 24 protected: 25 static bool ImportsCallback(const base::win::PEImage &image, 26 LPCSTR module, 27 PIMAGE_THUNK_DATA name_table, 28 PIMAGE_THUNK_DATA iat, 29 PVOID cookie) { 30 std::vector<std::string>* import_list = 31 reinterpret_cast<std::vector<std::string>*>(cookie); 32 import_list->push_back(module); 33 return true; 34 } 35 36 void GetImports(const base::FilePath& module_path, 37 std::vector<std::string>* imports) { 38 ASSERT_TRUE(imports != NULL); 39 40 base::MemoryMappedFile module_mmap; 41 42 ASSERT_TRUE(module_mmap.Initialize(module_path)); 43 base::win::PEImageAsData pe_image_data( 44 reinterpret_cast<HMODULE>(const_cast<uint8*>(module_mmap.data()))); 45 pe_image_data.EnumImportChunks(ELFImportsTest::ImportsCallback, imports); 46 } 47 }; 48 49 TEST_F(ELFImportsTest, ChromeElfSanityCheck) { 50 std::vector<std::string> elf_imports; 51 52 base::FilePath dll; 53 ASSERT_TRUE(PathService::Get(base::DIR_EXE, &dll)); 54 dll = dll.Append(L"chrome_elf.dll"); 55 GetImports(dll, &elf_imports); 56 57 // Check that ELF has imports. 58 ASSERT_LT(0u, elf_imports.size()) << "Ensure the chrome_elf_unittests " 59 "target was built, instead of chrome_elf_unittests.exe"; 60 61 std::vector<std::string>::iterator it(elf_imports.begin()); 62 63 static const char* const kValidFilePatterns[] = { 64 "KERNEL32.dll", 65 "MSVC*", 66 #if defined(SYZYASAN) 67 "syzyasan_rtl.dll", 68 #endif 69 "ADVAPI32.dll" 70 }; 71 72 // Make sure all of ELF's imports are in the valid imports list. 73 for (; it != elf_imports.end(); it++) { 74 bool match = false; 75 for (int i = 0; i < arraysize(kValidFilePatterns); ++i) { 76 if (MatchPattern(*it, kValidFilePatterns[i])) 77 match = true; 78 } 79 ASSERT_TRUE(match) << "Illegal import in chrome_elf.dll."; 80 } 81 } 82 83 TEST_F(ELFImportsTest, ChromeExeSanityCheck) { 84 std::vector<std::string> exe_imports; 85 86 base::FilePath exe; 87 ASSERT_TRUE(PathService::Get(base::DIR_EXE, &exe)); 88 exe = exe.Append(L"chrome.exe"); 89 GetImports(exe, &exe_imports); 90 91 // Check that chrome.exe has imports. 92 ASSERT_LT(0u, exe_imports.size()) << "Ensure the chrome_elf_unittests " 93 "target was built, instead of chrome_elf_unittests.exe"; 94 95 // Chrome.exe's first import must be ELF. 96 EXPECT_EQ("chrome_elf.dll", exe_imports[0]) << 97 "Illegal import order in chrome.exe (ensure the chrome_elf_unittest " 98 "target was built, instead of just chrome_elf_unittests.exe)"; 99 } 100 101 } // namespace 102