1effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// Copyright 2014 The Chromium Authors. All rights reserved. 2effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// found in the LICENSE file. 4effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 5effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "base/files/file_path.h" 6effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "base/files/memory_mapped_file.h" 7effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "base/path_service.h" 8effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "chrome/browser/safe_browsing/pe_image_reader_win.h" 9effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "chrome/common/chrome_paths.h" 10effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "testing/gtest/include/gtest/gtest.h" 11effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 12effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochstruct TestData { 13effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch const char* filename; 14effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch safe_browsing::PeImageReader::WordSize word_size; 15effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch WORD machine_identifier; 16effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch WORD optional_header_size; 17effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch size_t number_of_sections; 18effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch size_t number_of_debug_entries; 19effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}; 20effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 21effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// A test fixture parameterized on test data containing the name of a PE image 22effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// to parse and the expected values to be read from it. The file is read from 23effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// the src/chrome/test/data/safe_browsing directory. 24effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochclass PeImageReaderTest : public testing::TestWithParam<const TestData*> { 25effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch protected: 26effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch PeImageReaderTest() : expected_data_(GetParam()) {} 27effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 28effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch virtual void SetUp() OVERRIDE { 29effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &data_file_path_)); 30effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch data_file_path_ = data_file_path_.AppendASCII("safe_browsing"); 31effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch data_file_path_ = data_file_path_.AppendASCII(expected_data_->filename); 32effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 33effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch ASSERT_TRUE(data_file_.Initialize(data_file_path_)); 34effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 35effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch ASSERT_TRUE(image_reader_.Initialize(data_file_.data(), 36effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch data_file_.length())); 37effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 38effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 39effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch const TestData* expected_data_; 40effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch base::FilePath data_file_path_; 41effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch base::MemoryMappedFile data_file_; 42effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch safe_browsing::PeImageReader image_reader_; 43effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}; 44effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 45effb81e5f8246d0db0270817048dc992db66e9fbBen MurdochTEST_P(PeImageReaderTest, GetWordSize) { 46effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch EXPECT_EQ(expected_data_->word_size, image_reader_.GetWordSize()); 47effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 48effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 49effb81e5f8246d0db0270817048dc992db66e9fbBen MurdochTEST_P(PeImageReaderTest, GetDosHeader) { 50effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch const IMAGE_DOS_HEADER* dos_header = image_reader_.GetDosHeader(); 51effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch ASSERT_NE(reinterpret_cast<const IMAGE_DOS_HEADER*>(NULL), dos_header); 52effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch EXPECT_EQ(IMAGE_DOS_SIGNATURE, dos_header->e_magic); 53effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 54effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 55effb81e5f8246d0db0270817048dc992db66e9fbBen MurdochTEST_P(PeImageReaderTest, GetCoffFileHeader) { 56effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch const IMAGE_FILE_HEADER* file_header = image_reader_.GetCoffFileHeader(); 57effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch ASSERT_NE(reinterpret_cast<const IMAGE_FILE_HEADER*>(NULL), file_header); 58effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch EXPECT_EQ(expected_data_->machine_identifier, file_header->Machine); 59effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch EXPECT_EQ(expected_data_->optional_header_size, 60effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch file_header->SizeOfOptionalHeader); 61effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 62effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 63effb81e5f8246d0db0270817048dc992db66e9fbBen MurdochTEST_P(PeImageReaderTest, GetOptionalHeaderData) { 64effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch size_t optional_header_size = 0; 65effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch const uint8_t* optional_header_data = 66effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch image_reader_.GetOptionalHeaderData(&optional_header_size); 67effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch ASSERT_NE(reinterpret_cast<const uint8_t*>(NULL), optional_header_data); 68effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch EXPECT_EQ(expected_data_->optional_header_size, optional_header_size); 69effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 70effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 71effb81e5f8246d0db0270817048dc992db66e9fbBen MurdochTEST_P(PeImageReaderTest, GetNumberOfSections) { 72effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch EXPECT_EQ(expected_data_->number_of_sections, 73effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch image_reader_.GetNumberOfSections()); 74effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 75effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 76effb81e5f8246d0db0270817048dc992db66e9fbBen MurdochTEST_P(PeImageReaderTest, GetSectionHeaderAt) { 77effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch size_t number_of_sections = image_reader_.GetNumberOfSections(); 78effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch for (size_t i = 0; i < number_of_sections; ++i) { 79effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch const IMAGE_SECTION_HEADER* section_header = 80effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch image_reader_.GetSectionHeaderAt(i); 81effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch ASSERT_NE(reinterpret_cast<const IMAGE_SECTION_HEADER*>(NULL), 82effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch section_header); 83effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 84effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 85effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 86effb81e5f8246d0db0270817048dc992db66e9fbBen MurdochTEST_P(PeImageReaderTest, InitializeFailTruncatedFile) { 87effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // Compute the size of all headers through the section headers. 88effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch const IMAGE_SECTION_HEADER* last_section_header = 89effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch image_reader_.GetSectionHeaderAt(image_reader_.GetNumberOfSections() - 1); 90effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch const uint8_t* headers_end = 91effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch reinterpret_cast<const uint8_t*>(last_section_header) + 92effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch sizeof(*last_section_header); 93effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch size_t header_size = headers_end - data_file_.data(); 94effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch safe_browsing::PeImageReader short_reader; 95effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 96effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // Initialize should succeed when all headers are present. 97effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch EXPECT_TRUE(short_reader.Initialize(data_file_.data(), header_size)); 98effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 99effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // But fail if anything is missing. 100effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch for (size_t i = 0; i < header_size; ++i) { 101effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch EXPECT_FALSE(short_reader.Initialize(data_file_.data(), i)); 102effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 103effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 104effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 105effb81e5f8246d0db0270817048dc992db66e9fbBen MurdochTEST_P(PeImageReaderTest, GetExportSection) { 106effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch size_t section_size = 0; 107effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch const uint8_t* export_section = image_reader_.GetExportSection(§ion_size); 108effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch ASSERT_NE(reinterpret_cast<const uint8_t*>(NULL), export_section); 109effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch EXPECT_NE(0U, section_size); 110effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 111effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 112effb81e5f8246d0db0270817048dc992db66e9fbBen MurdochTEST_P(PeImageReaderTest, GetNumberOfDebugEntries) { 113effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch EXPECT_EQ(expected_data_->number_of_debug_entries, 114effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch image_reader_.GetNumberOfDebugEntries()); 115effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 116effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 117effb81e5f8246d0db0270817048dc992db66e9fbBen MurdochTEST_P(PeImageReaderTest, GetDebugEntry) { 118effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch size_t number_of_debug_entries = image_reader_.GetNumberOfDebugEntries(); 119effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch for (size_t i = 0; i < number_of_debug_entries; ++i) { 120effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch const uint8_t* raw_data = NULL; 121effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch size_t raw_data_size = 0; 122effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch const IMAGE_DEBUG_DIRECTORY* entry = 123effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch image_reader_.GetDebugEntry(i, &raw_data, &raw_data_size); 124effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch EXPECT_NE(reinterpret_cast<const IMAGE_DEBUG_DIRECTORY*>(NULL), entry); 125effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch EXPECT_NE(reinterpret_cast<const uint8_t*>(NULL), raw_data); 126effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch EXPECT_NE(0U, raw_data_size); 127effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 128effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 129effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 130effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochnamespace { 131effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 132effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochconst TestData kTestData[] = { 133effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch { 134effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch "module_with_exports_x86.dll", 135effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch safe_browsing::PeImageReader::WORD_SIZE_32, 136effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch IMAGE_FILE_MACHINE_I386, 137effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch sizeof(IMAGE_OPTIONAL_HEADER32), 138effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 4, 139effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 1, 140effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch }, { 141effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch "module_with_exports_x64.dll", 142effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch safe_browsing::PeImageReader::WORD_SIZE_64, 143effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch IMAGE_FILE_MACHINE_AMD64, 144effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch sizeof(IMAGE_OPTIONAL_HEADER64), 145effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 5, 146effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 1, 147effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch }, 148effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}; 149effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 150effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} // namespace 151effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 152effb81e5f8246d0db0270817048dc992db66e9fbBen MurdochINSTANTIATE_TEST_CASE_P(WordSize32, 153effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch PeImageReaderTest, 154effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch testing::Values(&kTestData[0])); 155effb81e5f8246d0db0270817048dc992db66e9fbBen MurdochINSTANTIATE_TEST_CASE_P(WordSize64, 156effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch PeImageReaderTest, 157effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch testing::Values(&kTestData[1])); 158