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> 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 259 int InterceptorFunction(int x) { 260 ++InterceptorFunctionCalled; 261 return InterceptedRealFunction(x); 262 } 263 264 } // namespace 265 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"); 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> 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 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 335 TEST(Interception, OverrideFunctionWithRedirectJump) { 336 TestOverrideFunction override = OverrideFunctionWithRedirectJump; 337 TestIdentityFunctionPatching(kIdentityCodeWithJump, override); 338 } 339 340 TEST(Interception, OverrideFunctionWithHotPatch) { 341 TestOverrideFunction override = OverrideFunctionWithHotPatch; 342 FunctionPrefixKind prefix = FunctionPrefixHotPatch; 343 TestIdentityFunctionPatching(kIdentityCodeWithMov, override, prefix); 344 } 345 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 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> 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 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 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> 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 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 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 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 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 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 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