|
1 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
2 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
4 |
|
5 #include <stdio.h> |
|
6 #include "nsWindowsDllInterceptor.h" |
|
7 |
|
8 using namespace mozilla; |
|
9 |
|
10 struct payload { |
|
11 UINT64 a; |
|
12 UINT64 b; |
|
13 UINT64 c; |
|
14 |
|
15 bool operator==(const payload &other) const { |
|
16 return (a == other.a && |
|
17 b == other.b && |
|
18 c == other.c); |
|
19 } |
|
20 }; |
|
21 |
|
22 extern "C" __declspec(dllexport) __declspec(noinline) payload rotatePayload(payload p) { |
|
23 UINT64 tmp = p.a; |
|
24 p.a = p.b; |
|
25 p.b = p.c; |
|
26 p.c = tmp; |
|
27 return p; |
|
28 } |
|
29 |
|
30 static bool patched_func_called = false; |
|
31 |
|
32 static payload (*orig_rotatePayload)(payload); |
|
33 |
|
34 static payload |
|
35 patched_rotatePayload(payload p) |
|
36 { |
|
37 patched_func_called = true; |
|
38 return orig_rotatePayload(p); |
|
39 } |
|
40 |
|
41 bool TestHook(const char *dll, const char *func) |
|
42 { |
|
43 void *orig_func; |
|
44 bool successful = false; |
|
45 { |
|
46 WindowsDllInterceptor TestIntercept; |
|
47 TestIntercept.Init(dll); |
|
48 successful = TestIntercept.AddHook(func, 0, &orig_func); |
|
49 } |
|
50 |
|
51 if (successful) { |
|
52 printf("TEST-PASS | WindowsDllInterceptor | Could hook %s from %s\n", func, dll); |
|
53 return true; |
|
54 } else { |
|
55 printf("TEST-UNEXPECTED-FAIL | WindowsDllInterceptor | Failed to hook %s from %s\n", func, dll); |
|
56 return false; |
|
57 } |
|
58 } |
|
59 |
|
60 bool TestDetour(const char *dll, const char *func) |
|
61 { |
|
62 void *orig_func; |
|
63 bool successful = false; |
|
64 { |
|
65 WindowsDllInterceptor TestIntercept; |
|
66 TestIntercept.Init(dll); |
|
67 successful = TestIntercept.AddDetour(func, 0, &orig_func); |
|
68 } |
|
69 |
|
70 if (successful) { |
|
71 printf("TEST-PASS | WindowsDllInterceptor | Could detour %s from %s\n", func, dll); |
|
72 return true; |
|
73 } else { |
|
74 printf("TEST-UNEXPECTED-FAIL | WindowsDllInterceptor | Failed to detour %s from %s\n", func, dll); |
|
75 return false; |
|
76 } |
|
77 } |
|
78 |
|
79 int main() |
|
80 { |
|
81 payload initial = { 0x12345678, 0xfc4e9d31, 0x87654321 }; |
|
82 payload p0, p1; |
|
83 ZeroMemory(&p0, sizeof(p0)); |
|
84 ZeroMemory(&p1, sizeof(p1)); |
|
85 |
|
86 p0 = rotatePayload(initial); |
|
87 |
|
88 { |
|
89 WindowsDllInterceptor ExeIntercept; |
|
90 ExeIntercept.Init("TestDllInterceptor.exe"); |
|
91 if (ExeIntercept.AddHook("rotatePayload", reinterpret_cast<intptr_t>(patched_rotatePayload), (void**) &orig_rotatePayload)) { |
|
92 printf("TEST-PASS | WindowsDllInterceptor | Hook added\n"); |
|
93 } else { |
|
94 printf("TEST-UNEXPECTED-FAIL | WindowsDllInterceptor | Failed to add hook\n"); |
|
95 return 1; |
|
96 } |
|
97 |
|
98 p1 = rotatePayload(initial); |
|
99 |
|
100 if (patched_func_called) { |
|
101 printf("TEST-PASS | WindowsDllInterceptor | Hook called\n"); |
|
102 } else { |
|
103 printf("TEST-UNEXPECTED-FAIL | WindowsDllInterceptor | Hook was not called\n"); |
|
104 return 1; |
|
105 } |
|
106 |
|
107 if (p0 == p1) { |
|
108 printf("TEST-PASS | WindowsDllInterceptor | Hook works properly\n"); |
|
109 } else { |
|
110 printf("TEST-UNEXPECTED-FAIL | WindowsDllInterceptor | Hook didn't return the right information\n"); |
|
111 return 1; |
|
112 } |
|
113 } |
|
114 |
|
115 patched_func_called = false; |
|
116 ZeroMemory(&p1, sizeof(p1)); |
|
117 |
|
118 p1 = rotatePayload(initial); |
|
119 |
|
120 if (!patched_func_called) { |
|
121 printf("TEST-PASS | WindowsDllInterceptor | Hook was not called after unregistration\n"); |
|
122 } else { |
|
123 printf("TEST-UNEXPECTED-FAIL | WindowsDllInterceptor | Hook was still called after unregistration\n"); |
|
124 return 1; |
|
125 } |
|
126 |
|
127 if (p0 == p1) { |
|
128 printf("TEST-PASS | WindowsDllInterceptor | Original function worked properly\n"); |
|
129 } else { |
|
130 printf("TEST-UNEXPECTED-FAIL | WindowsDllInterceptor | Original function didn't return the right information\n"); |
|
131 return 1; |
|
132 } |
|
133 |
|
134 if (TestHook("user32.dll", "GetWindowInfo") && |
|
135 #ifdef _WIN64 |
|
136 TestHook("user32.dll", "SetWindowLongPtrA") && |
|
137 TestHook("user32.dll", "SetWindowLongPtrW") && |
|
138 #else |
|
139 TestHook("user32.dll", "SetWindowLongA") && |
|
140 TestHook("user32.dll", "SetWindowLongW") && |
|
141 #endif |
|
142 TestHook("user32.dll", "TrackPopupMenu") && |
|
143 #ifdef _M_IX86 |
|
144 // We keep this test to hook complex code on x86. (Bug 850957) |
|
145 TestHook("ntdll.dll", "NtFlushBuffersFile") && |
|
146 #endif |
|
147 TestHook("ntdll.dll", "NtCreateFile") && |
|
148 TestHook("ntdll.dll", "NtReadFile") && |
|
149 TestHook("ntdll.dll", "NtReadFileScatter") && |
|
150 TestHook("ntdll.dll", "NtWriteFile") && |
|
151 TestHook("ntdll.dll", "NtWriteFileGather") && |
|
152 TestHook("ntdll.dll", "NtQueryFullAttributesFile") && |
|
153 // Bug 733892: toolkit/crashreporter/nsExceptionHandler.cpp |
|
154 TestHook("kernel32.dll", "SetUnhandledExceptionFilter") && |
|
155 #ifdef _M_IX86 |
|
156 // Bug 670967: xpcom/base/AvailableMemoryTracker.cpp |
|
157 TestHook("kernel32.dll", "VirtualAlloc") && |
|
158 TestHook("kernel32.dll", "MapViewOfFile") && |
|
159 TestHook("gdi32.dll", "CreateDIBSection") && |
|
160 #endif |
|
161 TestDetour("ntdll.dll", "LdrLoadDll")) { |
|
162 printf("TEST-PASS | WindowsDllInterceptor | all checks passed\n"); |
|
163 return 0; |
|
164 } |
|
165 |
|
166 return 1; |
|
167 } |