• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===-- interception_win_test.cc ------------------------------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file is a part of ThreadSanitizer/AddressSanitizer runtime.
11 // Tests for interception_win.h.
12 //
13 //===----------------------------------------------------------------------===//
14 #include "interception/interception.h"
15 
16 #include "gtest/gtest.h"
17 
18 // Too slow for debug build
19 #if !SANITIZER_DEBUG
20 #if SANITIZER_WINDOWS
21 
22 #define WIN32_LEAN_AND_MEAN
23 #include <windows.h>
24 
25 namespace __interception {
26 namespace {
27 
28 enum FunctionPrefixKind {
29   FunctionPrefixNone,
30   FunctionPrefixPadding,
31   FunctionPrefixHotPatch,
32   FunctionPrefixDetour,
33 };
34 
35 typedef bool (*TestOverrideFunction)(uptr, uptr, uptr*);
36 typedef int (*IdentityFunction)(int);
37 
38 #if SANITIZER_WINDOWS64
39 
40 const u8 kIdentityCodeWithPrologue[] = {
41     0x55,                   // push        rbp
42     0x48, 0x89, 0xE5,       // mov         rbp,rsp
43     0x8B, 0xC1,             // mov         eax,ecx
44     0x5D,                   // pop         rbp
45     0xC3,                   // ret
46 };
47 
48 const u8 kIdentityCodeWithPushPop[] = {
49     0x55,                   // push        rbp
50     0x48, 0x89, 0xE5,       // mov         rbp,rsp
51     0x53,                   // push        rbx
52     0x50,                   // push        rax
53     0x58,                   // pop         rax
54     0x8B, 0xC1,             // mov         rax,rcx
55     0x5B,                   // pop         rbx
56     0x5D,                   // pop         rbp
57     0xC3,                   // ret
58 };
59 
60 const u8 kIdentityTwiceOffset = 16;
61 const u8 kIdentityTwice[] = {
62     0x55,                   // push        rbp
63     0x48, 0x89, 0xE5,       // mov         rbp,rsp
64     0x8B, 0xC1,             // mov         eax,ecx
65     0x5D,                   // pop         rbp
66     0xC3,                   // ret
67     0x90, 0x90, 0x90, 0x90,
68     0x90, 0x90, 0x90, 0x90,
69     0x55,                   // push        rbp
70     0x48, 0x89, 0xE5,       // mov         rbp,rsp
71     0x8B, 0xC1,             // mov         eax,ecx
72     0x5D,                   // pop         rbp
73     0xC3,                   // ret
74 };
75 
76 const u8 kIdentityCodeWithMov[] = {
77     0x89, 0xC8,             // mov         eax, ecx
78     0xC3,                   // ret
79 };
80 
81 const u8 kIdentityCodeWithJump[] = {
82     0xE9, 0x04, 0x00, 0x00,
83     0x00,                   // jmp + 4
84     0xCC, 0xCC, 0xCC, 0xCC,
85     0x89, 0xC8,             // mov         eax, ecx
86     0xC3,                   // ret
87 };
88 
89 #else
90 
91 const u8 kIdentityCodeWithPrologue[] = {
92     0x55,                   // push        ebp
93     0x8B, 0xEC,             // mov         ebp,esp
94     0x8B, 0x45, 0x08,       // mov         eax,dword ptr [ebp + 8]
95     0x5D,                   // pop         ebp
96     0xC3,                   // ret
97 };
98 
99 const u8 kIdentityCodeWithPushPop[] = {
100     0x55,                   // push        ebp
101     0x8B, 0xEC,             // mov         ebp,esp
102     0x53,                   // push        ebx
103     0x50,                   // push        eax
104     0x58,                   // pop         eax
105     0x8B, 0x45, 0x08,       // mov         eax,dword ptr [ebp + 8]
106     0x5B,                   // pop         ebx
107     0x5D,                   // pop         ebp
108     0xC3,                   // ret
109 };
110 
111 const u8 kIdentityTwiceOffset = 8;
112 const u8 kIdentityTwice[] = {
113     0x55,                   // push        ebp
114     0x8B, 0xEC,             // mov         ebp,esp
115     0x8B, 0x45, 0x08,       // mov         eax,dword ptr [ebp + 8]
116     0x5D,                   // pop         ebp
117     0xC3,                   // ret
118     0x55,                   // push        ebp
119     0x8B, 0xEC,             // mov         ebp,esp
120     0x8B, 0x45, 0x08,       // mov         eax,dword ptr [ebp + 8]
121     0x5D,                   // pop         ebp
122     0xC3,                   // ret
123 };
124 
125 const u8 kIdentityCodeWithMov[] = {
126     0x8B, 0x44, 0x24, 0x04, // mov         eax,dword ptr [esp + 4]
127     0xC3,                   // ret
128 };
129 
130 const u8 kIdentityCodeWithJump[] = {
131     0xE9, 0x04, 0x00, 0x00,
132     0x00,                   // jmp + 4
133     0xCC, 0xCC, 0xCC, 0xCC,
134     0x8B, 0x44, 0x24, 0x04, // mov         eax,dword ptr [esp + 4]
135     0xC3,                   // ret
136 };
137 
138 #endif
139 
140 const u8 kPatchableCode1[] = {
141     0xB8, 0x4B, 0x00, 0x00, 0x00,   // mov eax,4B
142     0x33, 0xC9,                     // xor ecx,ecx
143     0xC3,                           // ret
144 };
145 
146 const u8 kPatchableCode2[] = {
147     0x55,                           // push ebp
148     0x8B, 0xEC,                     // mov ebp,esp
149     0x33, 0xC0,                     // xor eax,eax
150     0x5D,                           // pop ebp
151     0xC3,                           // ret
152 };
153 
154 const u8 kPatchableCode3[] = {
155     0x55,                           // push ebp
156     0x8B, 0xEC,                     // mov ebp,esp
157     0x6A, 0x00,                     // push 0
158     0xE8, 0x3D, 0xFF, 0xFF, 0xFF,   // call <func>
159 };
160 
161 const u8 kPatchableCode4[] = {
162     0xE9, 0xCC, 0xCC, 0xCC, 0xCC,   // jmp <label>
163     0x90, 0x90, 0x90, 0x90,
164 };
165 
166 const u8 kUnpatchableCode1[] = {
167     0xC3,                           // ret
168 };
169 
170 const u8 kUnpatchableCode2[] = {
171     0x33, 0xC9,                     // xor ecx,ecx
172     0xC3,                           // ret
173 };
174 
175 const u8 kUnpatchableCode3[] = {
176     0x75, 0xCC,                     // jne <label>
177     0x33, 0xC9,                     // xor ecx,ecx
178     0xC3,                           // ret
179 };
180 
181 const u8 kUnpatchableCode4[] = {
182     0x74, 0xCC,                     // jne <label>
183     0x33, 0xC9,                     // xor ecx,ecx
184     0xC3,                           // ret
185 };
186 
187 const u8 kUnpatchableCode5[] = {
188     0xEB, 0x02,                     // jmp <label>
189     0x33, 0xC9,                     // xor ecx,ecx
190     0xC3,                           // ret
191 };
192 
193 const u8 kUnpatchableCode6[] = {
194     0xE8, 0xCC, 0xCC, 0xCC, 0xCC,   // call <func>
195     0x90, 0x90, 0x90, 0x90,
196 };
197 
198 // A buffer holding the dynamically generated code under test.
199 u8* ActiveCode;
200 size_t ActiveCodeLength = 4096;
201 
202 template<class T>
LoadActiveCode(const T & code,uptr * entry_point,FunctionPrefixKind prefix_kind=FunctionPrefixNone)203 static void LoadActiveCode(
204     const T &code,
205     uptr *entry_point,
206     FunctionPrefixKind prefix_kind = FunctionPrefixNone) {
207   if (ActiveCode == nullptr) {
208     ActiveCode =
209         (u8*)::VirtualAlloc(nullptr, ActiveCodeLength,
210                             MEM_COMMIT | MEM_RESERVE,
211                             PAGE_EXECUTE_READWRITE);
212     ASSERT_NE(ActiveCode, nullptr);
213   }
214 
215   size_t position = 0;
216 
217   // Add padding to avoid memory violation when scanning the prefix.
218   for (int i = 0; i < 16; ++i)
219     ActiveCode[position++] = 0xC3;  // Instruction 'ret'.
220 
221   // Add function padding.
222   size_t padding = 0;
223   if (prefix_kind == FunctionPrefixPadding)
224     padding = 16;
225   else if (prefix_kind == FunctionPrefixDetour ||
226            prefix_kind == FunctionPrefixHotPatch)
227     padding = FIRST_32_SECOND_64(5, 6);
228   // Insert |padding| instructions 'nop'.
229   for (size_t i = 0; i < padding; ++i)
230     ActiveCode[position++] = 0x90;
231 
232   // Keep track of the entry point.
233   *entry_point = (uptr)&ActiveCode[position];
234 
235   // Add the detour instruction (i.e. mov edi, edi)
236   if (prefix_kind == FunctionPrefixDetour) {
237 #if SANITIZER_WINDOWS64
238     // Note that "mov edi,edi" is NOP in 32-bit only, in 64-bit it clears
239     // higher bits of RDI.
240     // Use 66,90H as NOP for Windows64.
241     ActiveCode[position++] = 0x66;
242     ActiveCode[position++] = 0x90;
243 #else
244     // mov edi,edi.
245     ActiveCode[position++] = 0x8B;
246     ActiveCode[position++] = 0xFF;
247 #endif
248 
249   }
250 
251   // Copy the function body.
252   for (size_t i = 0; i < sizeof(T); ++i)
253     ActiveCode[position++] = code[i];
254 }
255 
256 int InterceptorFunctionCalled;
257 IdentityFunction InterceptedRealFunction;
258 
InterceptorFunction(int x)259 int InterceptorFunction(int x) {
260   ++InterceptorFunctionCalled;
261   return InterceptedRealFunction(x);
262 }
263 
264 }  // namespace
265 
266 // Tests for interception_win.h
TEST(Interception,InternalGetProcAddress)267 TEST(Interception, InternalGetProcAddress) {
268   HMODULE ntdll_handle = ::GetModuleHandle("ntdll");
269   ASSERT_NE(nullptr, ntdll_handle);
270   uptr DbgPrint_expected = (uptr)::GetProcAddress(ntdll_handle, "DbgPrint");
271   uptr isdigit_expected = (uptr)::GetProcAddress(ntdll_handle, "isdigit");
272   uptr DbgPrint_adddress = InternalGetProcAddress(ntdll_handle, "DbgPrint");
273   uptr isdigit_address = InternalGetProcAddress(ntdll_handle, "isdigit");
274 
275   EXPECT_EQ(DbgPrint_expected, DbgPrint_adddress);
276   EXPECT_EQ(isdigit_expected, isdigit_address);
277   EXPECT_NE(DbgPrint_adddress, isdigit_address);
278 }
279 
280 template<class T>
TestIdentityFunctionPatching(const T & code,TestOverrideFunction override,FunctionPrefixKind prefix_kind=FunctionPrefixNone)281 static void TestIdentityFunctionPatching(
282     const T &code,
283     TestOverrideFunction override,
284     FunctionPrefixKind prefix_kind = FunctionPrefixNone) {
285   uptr identity_address;
286   LoadActiveCode(code, &identity_address, prefix_kind);
287   IdentityFunction identity = (IdentityFunction)identity_address;
288 
289   // Validate behavior before dynamic patching.
290   InterceptorFunctionCalled = 0;
291   EXPECT_EQ(0, identity(0));
292   EXPECT_EQ(42, identity(42));
293   EXPECT_EQ(0, InterceptorFunctionCalled);
294 
295   // Patch the function.
296   uptr real_identity_address = 0;
297   bool success = override(identity_address,
298                          (uptr)&InterceptorFunction,
299                          &real_identity_address);
300   EXPECT_TRUE(success);
301   EXPECT_NE(0U, real_identity_address);
302   IdentityFunction real_identity = (IdentityFunction)real_identity_address;
303   InterceptedRealFunction = real_identity;
304 
305   // Don't run tests if hooking failed or the real function is not valid.
306   if (!success || !real_identity_address)
307     return;
308 
309   // Calling the redirected function.
310   InterceptorFunctionCalled = 0;
311   EXPECT_EQ(0, identity(0));
312   EXPECT_EQ(42, identity(42));
313   EXPECT_EQ(2, InterceptorFunctionCalled);
314 
315   // Calling the real function.
316   InterceptorFunctionCalled = 0;
317   EXPECT_EQ(0, real_identity(0));
318   EXPECT_EQ(42, real_identity(42));
319   EXPECT_EQ(0, InterceptorFunctionCalled);
320 
321   TestOnlyReleaseTrampolineRegions();
322 }
323 
324 #if !SANITIZER_WINDOWS64
TEST(Interception,OverrideFunctionWithDetour)325 TEST(Interception, OverrideFunctionWithDetour) {
326   TestOverrideFunction override = OverrideFunctionWithDetour;
327   FunctionPrefixKind prefix = FunctionPrefixDetour;
328   TestIdentityFunctionPatching(kIdentityCodeWithPrologue, override, prefix);
329   TestIdentityFunctionPatching(kIdentityCodeWithPushPop, override, prefix);
330   TestIdentityFunctionPatching(kIdentityCodeWithMov, override, prefix);
331   TestIdentityFunctionPatching(kIdentityCodeWithJump, override, prefix);
332 }
333 #endif  // !SANITIZER_WINDOWS64
334 
TEST(Interception,OverrideFunctionWithRedirectJump)335 TEST(Interception, OverrideFunctionWithRedirectJump) {
336   TestOverrideFunction override = OverrideFunctionWithRedirectJump;
337   TestIdentityFunctionPatching(kIdentityCodeWithJump, override);
338 }
339 
TEST(Interception,OverrideFunctionWithHotPatch)340 TEST(Interception, OverrideFunctionWithHotPatch) {
341   TestOverrideFunction override = OverrideFunctionWithHotPatch;
342   FunctionPrefixKind prefix = FunctionPrefixHotPatch;
343   TestIdentityFunctionPatching(kIdentityCodeWithMov, override, prefix);
344 }
345 
TEST(Interception,OverrideFunctionWithTrampoline)346 TEST(Interception, OverrideFunctionWithTrampoline) {
347   TestOverrideFunction override = OverrideFunctionWithTrampoline;
348   FunctionPrefixKind prefix = FunctionPrefixNone;
349   TestIdentityFunctionPatching(kIdentityCodeWithPrologue, override, prefix);
350   TestIdentityFunctionPatching(kIdentityCodeWithPushPop, override, prefix);
351 
352   prefix = FunctionPrefixPadding;
353   TestIdentityFunctionPatching(kIdentityCodeWithPrologue, override, prefix);
354   TestIdentityFunctionPatching(kIdentityCodeWithPushPop, override, prefix);
355 }
356 
TEST(Interception,OverrideFunction)357 TEST(Interception, OverrideFunction) {
358   TestOverrideFunction override = OverrideFunction;
359   FunctionPrefixKind prefix = FunctionPrefixNone;
360   TestIdentityFunctionPatching(kIdentityCodeWithPrologue, override, prefix);
361   TestIdentityFunctionPatching(kIdentityCodeWithPushPop, override, prefix);
362   TestIdentityFunctionPatching(kIdentityCodeWithJump, override, prefix);
363 
364   prefix = FunctionPrefixPadding;
365   TestIdentityFunctionPatching(kIdentityCodeWithPrologue, override, prefix);
366   TestIdentityFunctionPatching(kIdentityCodeWithPushPop, override, prefix);
367   TestIdentityFunctionPatching(kIdentityCodeWithMov, override, prefix);
368   TestIdentityFunctionPatching(kIdentityCodeWithJump, override, prefix);
369 
370   prefix = FunctionPrefixHotPatch;
371   TestIdentityFunctionPatching(kIdentityCodeWithPrologue, override, prefix);
372   TestIdentityFunctionPatching(kIdentityCodeWithPushPop, override, prefix);
373   TestIdentityFunctionPatching(kIdentityCodeWithMov, override, prefix);
374   TestIdentityFunctionPatching(kIdentityCodeWithJump, override, prefix);
375 
376   prefix = FunctionPrefixDetour;
377   TestIdentityFunctionPatching(kIdentityCodeWithPrologue, override, prefix);
378   TestIdentityFunctionPatching(kIdentityCodeWithPushPop, override, prefix);
379   TestIdentityFunctionPatching(kIdentityCodeWithMov, override, prefix);
380   TestIdentityFunctionPatching(kIdentityCodeWithJump, override, prefix);
381 }
382 
383 template<class T>
TestIdentityFunctionMultiplePatching(const T & code,TestOverrideFunction override,FunctionPrefixKind prefix_kind=FunctionPrefixNone)384 static void TestIdentityFunctionMultiplePatching(
385     const T &code,
386     TestOverrideFunction override,
387     FunctionPrefixKind prefix_kind = FunctionPrefixNone) {
388   uptr identity_address;
389   LoadActiveCode(code, &identity_address, prefix_kind);
390 
391   // Patch the function.
392   uptr real_identity_address = 0;
393   bool success = override(identity_address,
394                           (uptr)&InterceptorFunction,
395                           &real_identity_address);
396   EXPECT_TRUE(success);
397   EXPECT_NE(0U, real_identity_address);
398 
399   // Re-patching the function should not work.
400   success = override(identity_address,
401                      (uptr)&InterceptorFunction,
402                      &real_identity_address);
403   EXPECT_FALSE(success);
404 
405   TestOnlyReleaseTrampolineRegions();
406 }
407 
TEST(Interception,OverrideFunctionMultiplePatchingIsFailing)408 TEST(Interception, OverrideFunctionMultiplePatchingIsFailing) {
409 #if !SANITIZER_WINDOWS64
410   TestIdentityFunctionMultiplePatching(kIdentityCodeWithPrologue,
411                                        OverrideFunctionWithDetour,
412                                        FunctionPrefixDetour);
413 #endif
414 
415   TestIdentityFunctionMultiplePatching(kIdentityCodeWithMov,
416                                        OverrideFunctionWithHotPatch,
417                                        FunctionPrefixHotPatch);
418 
419   TestIdentityFunctionMultiplePatching(kIdentityCodeWithPushPop,
420                                        OverrideFunctionWithTrampoline,
421                                        FunctionPrefixPadding);
422 }
423 
TEST(Interception,OverrideFunctionTwice)424 TEST(Interception, OverrideFunctionTwice) {
425   uptr identity_address1;
426   LoadActiveCode(kIdentityTwice, &identity_address1);
427   uptr identity_address2 = identity_address1 + kIdentityTwiceOffset;
428   IdentityFunction identity1 = (IdentityFunction)identity_address1;
429   IdentityFunction identity2 = (IdentityFunction)identity_address2;
430 
431   // Patch the two functions.
432   uptr real_identity_address = 0;
433   EXPECT_TRUE(OverrideFunction(identity_address1,
434                                (uptr)&InterceptorFunction,
435                                &real_identity_address));
436   EXPECT_TRUE(OverrideFunction(identity_address2,
437                                (uptr)&InterceptorFunction,
438                                &real_identity_address));
439   IdentityFunction real_identity = (IdentityFunction)real_identity_address;
440   InterceptedRealFunction = real_identity;
441 
442   // Calling the redirected function.
443   InterceptorFunctionCalled = 0;
444   EXPECT_EQ(42, identity1(42));
445   EXPECT_EQ(42, identity2(42));
446   EXPECT_EQ(2, InterceptorFunctionCalled);
447 
448   TestOnlyReleaseTrampolineRegions();
449 }
450 
451 template<class T>
TestFunctionPatching(const T & code,TestOverrideFunction override,FunctionPrefixKind prefix_kind=FunctionPrefixNone)452 static bool TestFunctionPatching(
453     const T &code,
454     TestOverrideFunction override,
455     FunctionPrefixKind prefix_kind = FunctionPrefixNone) {
456   uptr address;
457   LoadActiveCode(code, &address, prefix_kind);
458   uptr unused_real_address = 0;
459   bool result = override(
460       address, (uptr)&InterceptorFunction, &unused_real_address);
461 
462   TestOnlyReleaseTrampolineRegions();
463   return result;
464 }
465 
TEST(Interception,PatchableFunction)466 TEST(Interception, PatchableFunction) {
467   TestOverrideFunction override = OverrideFunction;
468   // Test without function padding.
469   EXPECT_TRUE(TestFunctionPatching(kPatchableCode1, override));
470   EXPECT_TRUE(TestFunctionPatching(kPatchableCode2, override));
471 #if SANITIZER_WINDOWS64
472   EXPECT_FALSE(TestFunctionPatching(kPatchableCode3, override));
473 #else
474   EXPECT_TRUE(TestFunctionPatching(kPatchableCode3, override));
475 #endif
476   EXPECT_TRUE(TestFunctionPatching(kPatchableCode4, override));
477 
478   EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode1, override));
479   EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode2, override));
480   EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode3, override));
481   EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode4, override));
482   EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode5, override));
483   EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode6, override));
484 }
485 
486 #if !SANITIZER_WINDOWS64
TEST(Interception,PatchableFunctionWithDetour)487 TEST(Interception, PatchableFunctionWithDetour) {
488   TestOverrideFunction override = OverrideFunctionWithDetour;
489   // Without the prefix, no function can be detoured.
490   EXPECT_FALSE(TestFunctionPatching(kPatchableCode1, override));
491   EXPECT_FALSE(TestFunctionPatching(kPatchableCode2, override));
492   EXPECT_FALSE(TestFunctionPatching(kPatchableCode3, override));
493   EXPECT_FALSE(TestFunctionPatching(kPatchableCode4, override));
494   EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode1, override));
495   EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode2, override));
496   EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode3, override));
497   EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode4, override));
498   EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode5, override));
499   EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode6, override));
500 
501   // With the prefix, all functions can be detoured.
502   FunctionPrefixKind prefix = FunctionPrefixDetour;
503   EXPECT_TRUE(TestFunctionPatching(kPatchableCode1, override, prefix));
504   EXPECT_TRUE(TestFunctionPatching(kPatchableCode2, override, prefix));
505   EXPECT_TRUE(TestFunctionPatching(kPatchableCode3, override, prefix));
506   EXPECT_TRUE(TestFunctionPatching(kPatchableCode4, override, prefix));
507   EXPECT_TRUE(TestFunctionPatching(kUnpatchableCode1, override, prefix));
508   EXPECT_TRUE(TestFunctionPatching(kUnpatchableCode2, override, prefix));
509   EXPECT_TRUE(TestFunctionPatching(kUnpatchableCode3, override, prefix));
510   EXPECT_TRUE(TestFunctionPatching(kUnpatchableCode4, override, prefix));
511   EXPECT_TRUE(TestFunctionPatching(kUnpatchableCode5, override, prefix));
512   EXPECT_TRUE(TestFunctionPatching(kUnpatchableCode6, override, prefix));
513 }
514 #endif  // !SANITIZER_WINDOWS64
515 
TEST(Interception,PatchableFunctionWithRedirectJump)516 TEST(Interception, PatchableFunctionWithRedirectJump) {
517   TestOverrideFunction override = OverrideFunctionWithRedirectJump;
518   EXPECT_FALSE(TestFunctionPatching(kPatchableCode1, override));
519   EXPECT_FALSE(TestFunctionPatching(kPatchableCode2, override));
520   EXPECT_FALSE(TestFunctionPatching(kPatchableCode3, override));
521   EXPECT_TRUE(TestFunctionPatching(kPatchableCode4, override));
522   EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode1, override));
523   EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode2, override));
524   EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode3, override));
525   EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode4, override));
526   EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode5, override));
527   EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode6, override));
528 }
529 
TEST(Interception,PatchableFunctionWithHotPatch)530 TEST(Interception, PatchableFunctionWithHotPatch) {
531   TestOverrideFunction override = OverrideFunctionWithHotPatch;
532   FunctionPrefixKind prefix = FunctionPrefixHotPatch;
533 
534   EXPECT_TRUE(TestFunctionPatching(kPatchableCode1, override, prefix));
535   EXPECT_FALSE(TestFunctionPatching(kPatchableCode2, override, prefix));
536   EXPECT_FALSE(TestFunctionPatching(kPatchableCode3, override, prefix));
537   EXPECT_FALSE(TestFunctionPatching(kPatchableCode4, override, prefix));
538 
539   EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode1, override, prefix));
540   EXPECT_TRUE(TestFunctionPatching(kUnpatchableCode2, override, prefix));
541   EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode3, override, prefix));
542   EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode4, override, prefix));
543   EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode5, override, prefix));
544   EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode6, override, prefix));
545 }
546 
TEST(Interception,PatchableFunctionWithTrampoline)547 TEST(Interception, PatchableFunctionWithTrampoline) {
548   TestOverrideFunction override = OverrideFunctionWithTrampoline;
549   FunctionPrefixKind prefix = FunctionPrefixPadding;
550 
551   EXPECT_TRUE(TestFunctionPatching(kPatchableCode1, override, prefix));
552   EXPECT_TRUE(TestFunctionPatching(kPatchableCode2, override, prefix));
553 #if SANITIZER_WINDOWS64
554   EXPECT_FALSE(TestFunctionPatching(kPatchableCode3, override, prefix));
555 #else
556   EXPECT_TRUE(TestFunctionPatching(kPatchableCode3, override, prefix));
557 #endif
558   EXPECT_FALSE(TestFunctionPatching(kPatchableCode4, override, prefix));
559 
560   EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode1, override, prefix));
561   EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode2, override, prefix));
562   EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode3, override, prefix));
563   EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode4, override, prefix));
564   EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode5, override, prefix));
565   EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode6, override, prefix));
566 }
567 
TEST(Interception,PatchableFunctionPadding)568 TEST(Interception, PatchableFunctionPadding) {
569   TestOverrideFunction override = OverrideFunction;
570   FunctionPrefixKind prefix = FunctionPrefixPadding;
571 
572   EXPECT_TRUE(TestFunctionPatching(kPatchableCode1, override, prefix));
573   EXPECT_TRUE(TestFunctionPatching(kPatchableCode2, override, prefix));
574 #if SANITIZER_WINDOWS64
575   EXPECT_FALSE(TestFunctionPatching(kPatchableCode3, override, prefix));
576 #else
577   EXPECT_TRUE(TestFunctionPatching(kPatchableCode3, override, prefix));
578 #endif
579   EXPECT_TRUE(TestFunctionPatching(kPatchableCode4, override, prefix));
580 
581   EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode1, override, prefix));
582   EXPECT_TRUE(TestFunctionPatching(kUnpatchableCode2, override, prefix));
583   EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode3, override, prefix));
584   EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode4, override, prefix));
585   EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode5, override, prefix));
586   EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode6, override, prefix));
587 }
588 
589 }  // namespace __interception
590 
591 #endif  // SANITIZER_WINDOWS
592 #endif  // #if !SANITIZER_DEBUG
593