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 |