1 //===-- interception_win_test.cc ------------------------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file is a part of ThreadSanitizer/AddressSanitizer runtime.
11 // Tests for interception_win.h.
13 //===----------------------------------------------------------------------===//
14 #include "interception/interception.h"
16 #include "gtest/gtest.h"
18 // Too slow for debug build
22 #define WIN32_LEAN_AND_MEAN
25 namespace __interception
{
28 enum FunctionPrefixKind
{
30 FunctionPrefixPadding
,
31 FunctionPrefixHotPatch
,
35 typedef bool (*TestOverrideFunction
)(uptr
, uptr
, uptr
*);
36 typedef int (*IdentityFunction
)(int);
38 #if SANITIZER_WINDOWS64
40 const u8 kIdentityCodeWithPrologue
[] = {
42 0x48, 0x89, 0xE5, // mov rbp,rsp
43 0x8B, 0xC1, // mov eax,ecx
48 const u8 kIdentityCodeWithPushPop
[] = {
50 0x48, 0x89, 0xE5, // mov rbp,rsp
54 0x8B, 0xC1, // mov rax,rcx
60 const u8 kIdentityTwiceOffset
= 16;
61 const u8 kIdentityTwice
[] = {
63 0x48, 0x89, 0xE5, // mov rbp,rsp
64 0x8B, 0xC1, // mov eax,ecx
67 0x90, 0x90, 0x90, 0x90,
68 0x90, 0x90, 0x90, 0x90,
70 0x48, 0x89, 0xE5, // mov rbp,rsp
71 0x8B, 0xC1, // mov eax,ecx
76 const u8 kIdentityCodeWithMov
[] = {
77 0x89, 0xC8, // mov eax, ecx
81 const u8 kIdentityCodeWithJump
[] = {
82 0xE9, 0x04, 0x00, 0x00,
84 0xCC, 0xCC, 0xCC, 0xCC,
85 0x89, 0xC8, // mov eax, ecx
91 const u8 kIdentityCodeWithPrologue
[] = {
93 0x8B, 0xEC, // mov ebp,esp
94 0x8B, 0x45, 0x08, // mov eax,dword ptr [ebp + 8]
99 const u8 kIdentityCodeWithPushPop
[] = {
101 0x8B, 0xEC, // mov ebp,esp
105 0x8B, 0x45, 0x08, // mov eax,dword ptr [ebp + 8]
111 const u8 kIdentityTwiceOffset
= 8;
112 const u8 kIdentityTwice
[] = {
114 0x8B, 0xEC, // mov ebp,esp
115 0x8B, 0x45, 0x08, // mov eax,dword ptr [ebp + 8]
119 0x8B, 0xEC, // mov ebp,esp
120 0x8B, 0x45, 0x08, // mov eax,dword ptr [ebp + 8]
125 const u8 kIdentityCodeWithMov
[] = {
126 0x8B, 0x44, 0x24, 0x04, // mov eax,dword ptr [esp + 4]
130 const u8 kIdentityCodeWithJump
[] = {
131 0xE9, 0x04, 0x00, 0x00,
133 0xCC, 0xCC, 0xCC, 0xCC,
134 0x8B, 0x44, 0x24, 0x04, // mov eax,dword ptr [esp + 4]
140 const u8 kPatchableCode1
[] = {
141 0xB8, 0x4B, 0x00, 0x00, 0x00, // mov eax,4B
142 0x33, 0xC9, // xor ecx,ecx
146 const u8 kPatchableCode2
[] = {
148 0x8B, 0xEC, // mov ebp,esp
149 0x33, 0xC0, // xor eax,eax
154 const u8 kPatchableCode3
[] = {
156 0x8B, 0xEC, // mov ebp,esp
157 0x6A, 0x00, // push 0
158 0xE8, 0x3D, 0xFF, 0xFF, 0xFF, // call <func>
161 const u8 kPatchableCode4
[] = {
162 0xE9, 0xCC, 0xCC, 0xCC, 0xCC, // jmp <label>
163 0x90, 0x90, 0x90, 0x90,
166 const u8 kUnpatchableCode1
[] = {
170 const u8 kUnpatchableCode2
[] = {
171 0x33, 0xC9, // xor ecx,ecx
175 const u8 kUnpatchableCode3
[] = {
176 0x75, 0xCC, // jne <label>
177 0x33, 0xC9, // xor ecx,ecx
181 const u8 kUnpatchableCode4
[] = {
182 0x74, 0xCC, // jne <label>
183 0x33, 0xC9, // xor ecx,ecx
187 const u8 kUnpatchableCode5
[] = {
188 0xEB, 0x02, // jmp <label>
189 0x33, 0xC9, // xor ecx,ecx
193 const u8 kUnpatchableCode6
[] = {
194 0xE8, 0xCC, 0xCC, 0xCC, 0xCC, // call <func>
195 0x90, 0x90, 0x90, 0x90,
198 // A buffer holding the dynamically generated code under test.
200 size_t ActiveCodeLength
= 4096;
203 static void LoadActiveCode(
206 FunctionPrefixKind prefix_kind
= FunctionPrefixNone
) {
207 if (ActiveCode
== nullptr) {
209 (u8
*)::VirtualAlloc(nullptr, ActiveCodeLength
,
210 MEM_COMMIT
| MEM_RESERVE
,
211 PAGE_EXECUTE_READWRITE
);
212 ASSERT_NE(ActiveCode
, nullptr);
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'.
221 // Add function padding.
223 if (prefix_kind
== FunctionPrefixPadding
)
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;
232 // Keep track of the entry point.
233 *entry_point
= (uptr
)&ActiveCode
[position
];
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;
245 ActiveCode
[position
++] = 0x8B;
246 ActiveCode
[position
++] = 0xFF;
251 // Copy the function body.
252 for (size_t i
= 0; i
< sizeof(T
); ++i
)
253 ActiveCode
[position
++] = code
[i
];
256 int InterceptorFunctionCalled
;
257 IdentityFunction InterceptedRealFunction
;
259 int InterceptorFunction(int x
) {
260 ++InterceptorFunctionCalled
;
261 return InterceptedRealFunction(x
);
266 // Tests for interception_win.h
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");
275 EXPECT_EQ(DbgPrint_expected
, DbgPrint_adddress
);
276 EXPECT_EQ(isdigit_expected
, isdigit_address
);
277 EXPECT_NE(DbgPrint_adddress
, isdigit_address
);
281 static void TestIdentityFunctionPatching(
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
;
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
);
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
;
305 // Don't run tests if hooking failed or the real function is not valid.
306 if (!success
|| !real_identity_address
)
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
);
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
);
321 TestOnlyReleaseTrampolineRegions();
324 #if !SANITIZER_WINDOWS64
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
);
333 #endif // !SANITIZER_WINDOWS64
335 TEST(Interception
, OverrideFunctionWithRedirectJump
) {
336 TestOverrideFunction override
= OverrideFunctionWithRedirectJump
;
337 TestIdentityFunctionPatching(kIdentityCodeWithJump
, override
);
340 TEST(Interception
, OverrideFunctionWithHotPatch
) {
341 TestOverrideFunction override
= OverrideFunctionWithHotPatch
;
342 FunctionPrefixKind prefix
= FunctionPrefixHotPatch
;
343 TestIdentityFunctionPatching(kIdentityCodeWithMov
, override
, prefix
);
346 TEST(Interception
, OverrideFunctionWithTrampoline
) {
347 TestOverrideFunction override
= OverrideFunctionWithTrampoline
;
348 FunctionPrefixKind prefix
= FunctionPrefixNone
;
349 TestIdentityFunctionPatching(kIdentityCodeWithPrologue
, override
, prefix
);
350 TestIdentityFunctionPatching(kIdentityCodeWithPushPop
, override
, prefix
);
352 prefix
= FunctionPrefixPadding
;
353 TestIdentityFunctionPatching(kIdentityCodeWithPrologue
, override
, prefix
);
354 TestIdentityFunctionPatching(kIdentityCodeWithPushPop
, override
, prefix
);
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
);
364 prefix
= FunctionPrefixPadding
;
365 TestIdentityFunctionPatching(kIdentityCodeWithPrologue
, override
, prefix
);
366 TestIdentityFunctionPatching(kIdentityCodeWithPushPop
, override
, prefix
);
367 TestIdentityFunctionPatching(kIdentityCodeWithMov
, override
, prefix
);
368 TestIdentityFunctionPatching(kIdentityCodeWithJump
, override
, prefix
);
370 prefix
= FunctionPrefixHotPatch
;
371 TestIdentityFunctionPatching(kIdentityCodeWithPrologue
, override
, prefix
);
372 TestIdentityFunctionPatching(kIdentityCodeWithPushPop
, override
, prefix
);
373 TestIdentityFunctionPatching(kIdentityCodeWithMov
, override
, prefix
);
374 TestIdentityFunctionPatching(kIdentityCodeWithJump
, override
, prefix
);
376 prefix
= FunctionPrefixDetour
;
377 TestIdentityFunctionPatching(kIdentityCodeWithPrologue
, override
, prefix
);
378 TestIdentityFunctionPatching(kIdentityCodeWithPushPop
, override
, prefix
);
379 TestIdentityFunctionPatching(kIdentityCodeWithMov
, override
, prefix
);
380 TestIdentityFunctionPatching(kIdentityCodeWithJump
, override
, prefix
);
384 static void TestIdentityFunctionMultiplePatching(
386 TestOverrideFunction override
,
387 FunctionPrefixKind prefix_kind
= FunctionPrefixNone
) {
388 uptr identity_address
;
389 LoadActiveCode(code
, &identity_address
, prefix_kind
);
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
);
399 // Re-patching the function should not work.
400 success
= override(identity_address
,
401 (uptr
)&InterceptorFunction
,
402 &real_identity_address
);
403 EXPECT_FALSE(success
);
405 TestOnlyReleaseTrampolineRegions();
408 TEST(Interception
, OverrideFunctionMultiplePatchingIsFailing
) {
409 #if !SANITIZER_WINDOWS64
410 TestIdentityFunctionMultiplePatching(kIdentityCodeWithPrologue
,
411 OverrideFunctionWithDetour
,
412 FunctionPrefixDetour
);
415 TestIdentityFunctionMultiplePatching(kIdentityCodeWithMov
,
416 OverrideFunctionWithHotPatch
,
417 FunctionPrefixHotPatch
);
419 TestIdentityFunctionMultiplePatching(kIdentityCodeWithPushPop
,
420 OverrideFunctionWithTrampoline
,
421 FunctionPrefixPadding
);
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
;
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
;
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
);
448 TestOnlyReleaseTrampolineRegions();
452 static bool TestFunctionPatching(
454 TestOverrideFunction override
,
455 FunctionPrefixKind prefix_kind
= FunctionPrefixNone
) {
457 LoadActiveCode(code
, &address
, prefix_kind
);
458 uptr unused_real_address
= 0;
459 bool result
= override(
460 address
, (uptr
)&InterceptorFunction
, &unused_real_address
);
462 TestOnlyReleaseTrampolineRegions();
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
));
474 EXPECT_TRUE(TestFunctionPatching(kPatchableCode3
, override
));
476 EXPECT_TRUE(TestFunctionPatching(kPatchableCode4
, override
));
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
));
486 #if !SANITIZER_WINDOWS64
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
));
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
));
514 #endif // !SANITIZER_WINDOWS64
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
));
530 TEST(Interception
, PatchableFunctionWithHotPatch
) {
531 TestOverrideFunction override
= OverrideFunctionWithHotPatch
;
532 FunctionPrefixKind prefix
= FunctionPrefixHotPatch
;
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
));
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
));
547 TEST(Interception
, PatchableFunctionWithTrampoline
) {
548 TestOverrideFunction override
= OverrideFunctionWithTrampoline
;
549 FunctionPrefixKind prefix
= FunctionPrefixPadding
;
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
));
556 EXPECT_TRUE(TestFunctionPatching(kPatchableCode3
, override
, prefix
));
558 EXPECT_FALSE(TestFunctionPatching(kPatchableCode4
, override
, prefix
));
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
));
568 TEST(Interception
, PatchableFunctionPadding
) {
569 TestOverrideFunction override
= OverrideFunction
;
570 FunctionPrefixKind prefix
= FunctionPrefixPadding
;
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
));
577 EXPECT_TRUE(TestFunctionPatching(kPatchableCode3
, override
, prefix
));
579 EXPECT_TRUE(TestFunctionPatching(kPatchableCode4
, override
, prefix
));
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
));
589 } // namespace __interception
591 #endif // SANITIZER_WINDOWS
592 #endif // #if !SANITIZER_DEBUG