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