| OLD | NEW |
| (Empty) |
| 1 // Copyright 2016 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 <windows.h> | |
| 6 | |
| 7 #include "chrome_elf/hook_util/hook_util.h" | |
| 8 // Compile in this test DLL, so that it's in the IAT. | |
| 9 #include "chrome_elf/hook_util/test/hook_util_test_dll.h" | |
| 10 #include "testing/gtest/include/gtest/gtest.h" | |
| 11 | |
| 12 namespace { | |
| 13 | |
| 14 // IATHook test constants. | |
| 15 const char kIATTestDllName[] = "hook_util_test_dll.dll"; | |
| 16 const char kIATExportedApiFunction[] = "ExportedApi"; | |
| 17 | |
| 18 // IATHook function, which does nothing. | |
| 19 void IATHookedExportedApi() { | |
| 20 return; | |
| 21 } | |
| 22 | |
| 23 // Shady third-party IATHook function, which also does nothing, but different | |
| 24 // chunk of code/address. | |
| 25 void IATHookedExportedApiTwo() { | |
| 26 printf("Something to make this function different!\n"); | |
| 27 return; | |
| 28 } | |
| 29 | |
| 30 class HookTest : public testing::Test { | |
| 31 protected: | |
| 32 HookTest() {} | |
| 33 }; | |
| 34 | |
| 35 //------------------------------------------------------------------------------ | |
| 36 // IATHook tests | |
| 37 //------------------------------------------------------------------------------ | |
| 38 | |
| 39 TEST_F(HookTest, IATHook) { | |
| 40 // Sanity test with no hook. | |
| 41 ASSERT_EQ(0, ExportedApiCallCount()); | |
| 42 ExportedApi(); | |
| 43 ExportedApi(); | |
| 44 ASSERT_EQ(2, ExportedApiCallCount()); | |
| 45 | |
| 46 // Apply IAT hook. | |
| 47 elf_hook::IATHook iat_hook; | |
| 48 if (iat_hook.Hook(::GetModuleHandle(nullptr), kIATTestDllName, | |
| 49 kIATExportedApiFunction, | |
| 50 IATHookedExportedApi) != NO_ERROR) { | |
| 51 ADD_FAILURE(); | |
| 52 return; | |
| 53 } | |
| 54 | |
| 55 // Make sure hooking twice with the same object fails. | |
| 56 if (iat_hook.Hook(::GetModuleHandle(nullptr), kIATTestDllName, | |
| 57 kIATExportedApiFunction, | |
| 58 IATHookedExportedApi) != ERROR_SHARING_VIOLATION) | |
| 59 ADD_FAILURE(); | |
| 60 | |
| 61 // Call count should not change with hook. | |
| 62 ExportedApi(); | |
| 63 ExportedApi(); | |
| 64 ExportedApi(); | |
| 65 EXPECT_EQ(2, ExportedApiCallCount()); | |
| 66 | |
| 67 // Remove hook. | |
| 68 if (iat_hook.Unhook() != NO_ERROR) | |
| 69 ADD_FAILURE(); | |
| 70 | |
| 71 // Sanity test things are back to normal. | |
| 72 ExportedApi(); | |
| 73 EXPECT_EQ(3, ExportedApiCallCount()); | |
| 74 | |
| 75 // Double unhook should fail. | |
| 76 if (iat_hook.Unhook() != ERROR_INVALID_PARAMETER) | |
| 77 ADD_FAILURE(); | |
| 78 | |
| 79 // Try hooking a non-existent function. | |
| 80 if (iat_hook.Hook(::GetModuleHandle(nullptr), kIATTestDllName, "FooBarred", | |
| 81 IATHookedExportedApi) != ERROR_PROC_NOT_FOUND) | |
| 82 ADD_FAILURE(); | |
| 83 | |
| 84 // Test the case where someone else hooks our hook! Unhook() should leave it. | |
| 85 if (iat_hook.Hook(::GetModuleHandle(nullptr), kIATTestDllName, | |
| 86 kIATExportedApiFunction, | |
| 87 IATHookedExportedApi) != NO_ERROR) { | |
| 88 ADD_FAILURE(); | |
| 89 return; | |
| 90 } | |
| 91 elf_hook::IATHook shady_third_party_iat_hook; | |
| 92 if (shady_third_party_iat_hook.Hook(::GetModuleHandle(nullptr), | |
| 93 kIATTestDllName, kIATExportedApiFunction, | |
| 94 IATHookedExportedApiTwo) != NO_ERROR) | |
| 95 ADD_FAILURE(); | |
| 96 if (iat_hook.Unhook() != ERROR_INVALID_FUNCTION) | |
| 97 ADD_FAILURE(); | |
| 98 if (shady_third_party_iat_hook.Unhook() != NO_ERROR) | |
| 99 ADD_FAILURE(); | |
| 100 // NOTE: the first hook was left in and couldn't be cleaned up. | |
| 101 } | |
| 102 | |
| 103 } // namespace | |
| OLD | NEW |