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