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 |