1c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved. 2c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// found in the LICENSE file. 4c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 5c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <windows.h> 6c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#if defined(_WIN32_WINNT_WIN8) && _MSC_VER < 1700 7c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// The Windows 8 SDK defines FACILITY_VISUALCPP in winerror.h, and in 8c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// delayimp.h previous to VS2012. 9c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#undef FACILITY_VISUALCPP 10c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#endif 11c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <DelayIMP.h> 12c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 13c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/basictypes.h" 14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/compiler_specific.h" 15c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/scoped_native_library.h" 16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/app/delay_load_hook_win.h" 17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 18c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 19c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace { 20c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class ChromeDelayLoadHookTest : public testing::Test { 22c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public: 23c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ChromeDelayLoadHookTest() : proc_ptr_(NULL) { 24c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual void SetUp() OVERRIDE { 27c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SetupInfo("kernel32.dll"); 28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 30c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void SetupInfo(const char* dll_name) { 31c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) info_.cb = sizeof(info_); 32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) info_.pidd = NULL; 33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) info_.ppfn = &proc_ptr_; 34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) info_.szDll = dll_name; 35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) info_.dlp.fImportByName = TRUE; 36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) info_.dlp.szProcName = "CreateFileA"; 37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) info_.hmodCur = NULL; 38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) info_.pfnCur = NULL; 39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) info_.dwLastError = 0; 40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FARPROC proc_ptr_; 43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DelayLoadInfo info_; 44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}; 45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} // namespace 47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(ChromeDelayLoadHookTest, HooksAreSetAtLinkTime) { 49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // This test verifies that referencing the ChromeDelayLoadHook at link 50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // time results in overriding the delay loader's hook instances in the CRT 51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // ropriately. 52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(__pfnDliNotifyHook2 == ChromeDelayLoadHook); 53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(__pfnDliFailureHook2 == ChromeDelayLoadHook); 54c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(ChromeDelayLoadHookTest, NonSuffixedDllsAreNotHandled) { 57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // The hook should ignore non-suffixed DLLs. 58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SetupInfo("kernel32.dll"); 59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) HMODULE none = reinterpret_cast<HMODULE>( 61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ChromeDelayLoadHook(dliNotePreLoadLibrary, &info_)); 62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Make sure the library is released on exit. 63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::ScopedNativeLibrary lib_holder(none); 64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_TRUE(none == NULL); 66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(ChromeDelayLoadHookTest, SuffixedDllsAreRedirected) { 69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Check that a DLL name of the form "foo-delay.dll" gets redirected to 70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // the "foo.dll". 71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SetupInfo("kernel32-delay.dll"); 72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) HMODULE kernel32 = reinterpret_cast<HMODULE>( 73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ChromeDelayLoadHook(dliNotePreLoadLibrary, &info_)); 74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Make sure the library is released on exit. 76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::ScopedNativeLibrary lib_holder(kernel32); 77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_TRUE(kernel32 == ::GetModuleHandle(L"kernel32.dll")); 79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(ChromeDelayLoadHookTest, IgnoresUnhandledNotifications) { 82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SetupInfo("kernel32-delay.dll"); 83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // The hook should ignore all notifications but the preload notifications. 85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(ChromeDelayLoadHook(dliNoteStartProcessing, &info_) == NULL); 86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(ChromeDelayLoadHook(dliNotePreGetProcAddress, &info_) == NULL); 87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(ChromeDelayLoadHook(dliNoteEndProcessing, &info_) == NULL); 88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(ChromeDelayLoadHook(dliFailLoadLib, &info_) == NULL); 89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(ChromeDelayLoadHook(dliFailGetProc, &info_) == NULL); 90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 91