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 kUnpatchableCode7[] = { 212 0x33, 0xc0, // xor eax,eax 213 0x48, 0x85, 0xd2, // test rdx,rdx 214 0x74, 0x10, // je +16 (unpatchable) 215 }; 216 217 const u8 kUnpatchableCode8[] = { 218 0x48, 0x8b, 0xc1, // mov rax,rcx 219 0x0f, 0xb7, 0x10, // movzx edx,word ptr [rax] 220 0x48, 0x83, 0xc0, 0x02, // add rax,2 221 0x66, 0x85, 0xd2, // test dx,dx 222 0x75, 0xf4, // jne -12 (unpatchable) 223 }; 224 225 const u8 kUnpatchableCode9[] = { 226 0x4c, 0x8b, 0xc1, // mov r8,rcx 227 0x8a, 0x01, // mov al,byte ptr [rcx] 228 0x48, 0xff, 0xc1, // inc rcx 229 0x84, 0xc0, // test al,al 230 0x75, 0xf7, // jne -9 (unpatchable) 231 }; 232 233 const u8 kPatchableCode6[] = { 234 0x48, 0x89, 0x54, 0x24, 0xBB, // mov QWORD PTR [rsp + 0xBB], rdx 235 0x33, 0xC9, // xor ecx,ecx 236 0xC3, // ret 237 }; 238 239 const u8 kPatchableCode7[] = { 240 0x4c, 0x89, 0x4c, 0x24, 0xBB, // mov QWORD PTR [rsp + 0xBB], r9 241 0x33, 0xC9, // xor ecx,ecx 242 0xC3, // ret 243 }; 244 245 const u8 kPatchableCode8[] = { 246 0x4c, 0x89, 0x44, 0x24, 0xBB, // mov QWORD PTR [rsp + 0xBB], r8 247 0x33, 0xC9, // xor ecx,ecx 248 0xC3, // ret 249 }; 250 251 const u8 kPatchableCode9[] = { 252 0x8a, 0x01, // al,byte ptr [rcx] 253 0x45, 0x33, 0xc0, // xor r8d,r8d 254 0x84, 0xc0, // test al,al 255 }; 256 257 const u8 kPatchableCode10[] = { 258 0x45, 0x33, 0xc0, // xor r8d,r8d 259 0x41, 0x8b, 0xc0, // mov eax,r8d 260 0x48, 0x85, 0xd2, // test rdx,rdx 261 }; 262 263 const u8 kPatchableCode11[] = { 264 0x48, 0x83, 0xec, 0x38, // sub rsp,38h 265 0x83, 0x64, 0x24, 0x28, 0x00, // and dword ptr [rsp+28h],0 266 }; 267 268 // A buffer holding the dynamically generated code under test. 269 u8* ActiveCode; 270 const size_t ActiveCodeLength = 4096; 271 272 int InterceptorFunction(int x); 273 274 /// Allocate code memory more than 2GB away from Base. 275 u8 *AllocateCode2GBAway(u8 *Base) { 276 // Find a 64K aligned location after Base plus 2GB. 277 size_t TwoGB = 0x80000000; 278 size_t AllocGranularity = 0x10000; 279 Base = (u8 *)((((uptr)Base + TwoGB + AllocGranularity)) & ~(AllocGranularity - 1)); 280 281 // Check if that location is free, and if not, loop over regions until we find 282 // one that is. 283 MEMORY_BASIC_INFORMATION mbi = {}; 284 while (sizeof(mbi) == VirtualQuery(Base, &mbi, sizeof(mbi))) { 285 if (mbi.State & MEM_FREE) break; 286 Base += mbi.RegionSize; 287 } 288 289 // Allocate one RWX page at the free location. 290 return (u8 *)::VirtualAlloc(Base, ActiveCodeLength, MEM_COMMIT | MEM_RESERVE, 291 PAGE_EXECUTE_READWRITE); 292 } 293 294 template<class T> 295 static void LoadActiveCode( 296 const T &code, 297 uptr *entry_point, 298 FunctionPrefixKind prefix_kind = FunctionPrefixNone) { 299 if (ActiveCode == nullptr) { 300 ActiveCode = AllocateCode2GBAway((u8*)&InterceptorFunction); 301 ASSERT_NE(ActiveCode, nullptr) << "failed to allocate RWX memory 2GB away"; 302 } 303 304 size_t position = 0; 305 306 // Add padding to avoid memory violation when scanning the prefix. 307 for (int i = 0; i < 16; ++i) 308 ActiveCode[position++] = 0xC3; // Instruction 'ret'. 309 310 // Add function padding. 311 size_t padding = 0; 312 if (prefix_kind == FunctionPrefixPadding) 313 padding = 16; 314 else if (prefix_kind == FunctionPrefixDetour || 315 prefix_kind == FunctionPrefixHotPatch) 316 padding = FIRST_32_SECOND_64(5, 6); 317 // Insert |padding| instructions 'nop'. 318 for (size_t i = 0; i < padding; ++i) 319 ActiveCode[position++] = 0x90; 320 321 // Keep track of the entry point. 322 *entry_point = (uptr)&ActiveCode[position]; 323 324 // Add the detour instruction (i.e. mov edi, edi) 325 if (prefix_kind == FunctionPrefixDetour) { 326 #if SANITIZER_WINDOWS64 327 // Note that "mov edi,edi" is NOP in 32-bit only, in 64-bit it clears 328 // higher bits of RDI. 329 // Use 66,90H as NOP for Windows64. 330 ActiveCode[position++] = 0x66; 331 ActiveCode[position++] = 0x90; 332 #else 333 // mov edi,edi. 334 ActiveCode[position++] = 0x8B; 335 ActiveCode[position++] = 0xFF; 336 #endif 337 338 } 339 340 // Copy the function body. 341 for (size_t i = 0; i < sizeof(T); ++i) 342 ActiveCode[position++] = code[i]; 343 } 344 345 int InterceptorFunctionCalled; 346 IdentityFunction InterceptedRealFunction; 347 348 int InterceptorFunction(int x) { 349 ++InterceptorFunctionCalled; 350 return InterceptedRealFunction(x); 351 } 352 353 } // namespace 354 355 // Tests for interception_win.h 356 TEST(Interception, InternalGetProcAddress) { 357 HMODULE ntdll_handle = ::GetModuleHandle("ntdll"); 358 ASSERT_NE(nullptr, ntdll_handle); 359 uptr DbgPrint_expected = (uptr)::GetProcAddress(ntdll_handle, "DbgPrint"); 360 uptr isdigit_expected = (uptr)::GetProcAddress(ntdll_handle, "isdigit"); 361 uptr DbgPrint_adddress = InternalGetProcAddress(ntdll_handle, "DbgPrint"); 362 uptr isdigit_address = InternalGetProcAddress(ntdll_handle, "isdigit"); 363 364 EXPECT_EQ(DbgPrint_expected, DbgPrint_adddress); 365 EXPECT_EQ(isdigit_expected, isdigit_address); 366 EXPECT_NE(DbgPrint_adddress, isdigit_address); 367 } 368 369 template<class T> 370 static void TestIdentityFunctionPatching( 371 const T &code, 372 TestOverrideFunction override, 373 FunctionPrefixKind prefix_kind = FunctionPrefixNone) { 374 uptr identity_address; 375 LoadActiveCode(code, &identity_address, prefix_kind); 376 IdentityFunction identity = (IdentityFunction)identity_address; 377 378 // Validate behavior before dynamic patching. 379 InterceptorFunctionCalled = 0; 380 EXPECT_EQ(0, identity(0)); 381 EXPECT_EQ(42, identity(42)); 382 EXPECT_EQ(0, InterceptorFunctionCalled); 383 384 // Patch the function. 385 uptr real_identity_address = 0; 386 bool success = override(identity_address, 387 (uptr)&InterceptorFunction, 388 &real_identity_address); 389 EXPECT_TRUE(success); 390 EXPECT_NE(0U, real_identity_address); 391 IdentityFunction real_identity = (IdentityFunction)real_identity_address; 392 InterceptedRealFunction = real_identity; 393 394 // Don't run tests if hooking failed or the real function is not valid. 395 if (!success || !real_identity_address) 396 return; 397 398 // Calling the redirected function. 399 InterceptorFunctionCalled = 0; 400 EXPECT_EQ(0, identity(0)); 401 EXPECT_EQ(42, identity(42)); 402 EXPECT_EQ(2, InterceptorFunctionCalled); 403 404 // Calling the real function. 405 InterceptorFunctionCalled = 0; 406 EXPECT_EQ(0, real_identity(0)); 407 EXPECT_EQ(42, real_identity(42)); 408 EXPECT_EQ(0, InterceptorFunctionCalled); 409 410 TestOnlyReleaseTrampolineRegions(); 411 } 412 413 #if !SANITIZER_WINDOWS64 414 TEST(Interception, OverrideFunctionWithDetour) { 415 TestOverrideFunction override = OverrideFunctionWithDetour; 416 FunctionPrefixKind prefix = FunctionPrefixDetour; 417 TestIdentityFunctionPatching(kIdentityCodeWithPrologue, override, prefix); 418 TestIdentityFunctionPatching(kIdentityCodeWithPushPop, override, prefix); 419 TestIdentityFunctionPatching(kIdentityCodeWithMov, override, prefix); 420 TestIdentityFunctionPatching(kIdentityCodeWithJump, override, prefix); 421 } 422 #endif // !SANITIZER_WINDOWS64 423 424 TEST(Interception, OverrideFunctionWithRedirectJump) { 425 TestOverrideFunction override = OverrideFunctionWithRedirectJump; 426 TestIdentityFunctionPatching(kIdentityCodeWithJump, override); 427 } 428 429 TEST(Interception, OverrideFunctionWithHotPatch) { 430 TestOverrideFunction override = OverrideFunctionWithHotPatch; 431 FunctionPrefixKind prefix = FunctionPrefixHotPatch; 432 TestIdentityFunctionPatching(kIdentityCodeWithMov, override, prefix); 433 } 434 435 TEST(Interception, OverrideFunctionWithTrampoline) { 436 TestOverrideFunction override = OverrideFunctionWithTrampoline; 437 FunctionPrefixKind prefix = FunctionPrefixNone; 438 TestIdentityFunctionPatching(kIdentityCodeWithPrologue, override, prefix); 439 TestIdentityFunctionPatching(kIdentityCodeWithPushPop, override, prefix); 440 441 prefix = FunctionPrefixPadding; 442 TestIdentityFunctionPatching(kIdentityCodeWithPrologue, override, prefix); 443 TestIdentityFunctionPatching(kIdentityCodeWithPushPop, override, prefix); 444 } 445 446 TEST(Interception, OverrideFunction) { 447 TestOverrideFunction override = OverrideFunction; 448 FunctionPrefixKind prefix = FunctionPrefixNone; 449 TestIdentityFunctionPatching(kIdentityCodeWithPrologue, override, prefix); 450 TestIdentityFunctionPatching(kIdentityCodeWithPushPop, override, prefix); 451 TestIdentityFunctionPatching(kIdentityCodeWithJump, override, prefix); 452 453 prefix = FunctionPrefixPadding; 454 TestIdentityFunctionPatching(kIdentityCodeWithPrologue, override, prefix); 455 TestIdentityFunctionPatching(kIdentityCodeWithPushPop, override, prefix); 456 TestIdentityFunctionPatching(kIdentityCodeWithMov, override, prefix); 457 TestIdentityFunctionPatching(kIdentityCodeWithJump, override, prefix); 458 459 prefix = FunctionPrefixHotPatch; 460 TestIdentityFunctionPatching(kIdentityCodeWithPrologue, override, prefix); 461 TestIdentityFunctionPatching(kIdentityCodeWithPushPop, override, prefix); 462 TestIdentityFunctionPatching(kIdentityCodeWithMov, override, prefix); 463 TestIdentityFunctionPatching(kIdentityCodeWithJump, override, prefix); 464 465 prefix = FunctionPrefixDetour; 466 TestIdentityFunctionPatching(kIdentityCodeWithPrologue, override, prefix); 467 TestIdentityFunctionPatching(kIdentityCodeWithPushPop, override, prefix); 468 TestIdentityFunctionPatching(kIdentityCodeWithMov, override, prefix); 469 TestIdentityFunctionPatching(kIdentityCodeWithJump, override, prefix); 470 } 471 472 template<class T> 473 static void TestIdentityFunctionMultiplePatching( 474 const T &code, 475 TestOverrideFunction override, 476 FunctionPrefixKind prefix_kind = FunctionPrefixNone) { 477 uptr identity_address; 478 LoadActiveCode(code, &identity_address, prefix_kind); 479 480 // Patch the function. 481 uptr real_identity_address = 0; 482 bool success = override(identity_address, 483 (uptr)&InterceptorFunction, 484 &real_identity_address); 485 EXPECT_TRUE(success); 486 EXPECT_NE(0U, real_identity_address); 487 488 // Re-patching the function should not work. 489 success = override(identity_address, 490 (uptr)&InterceptorFunction, 491 &real_identity_address); 492 EXPECT_FALSE(success); 493 494 TestOnlyReleaseTrampolineRegions(); 495 } 496 497 TEST(Interception, OverrideFunctionMultiplePatchingIsFailing) { 498 #if !SANITIZER_WINDOWS64 499 TestIdentityFunctionMultiplePatching(kIdentityCodeWithPrologue, 500 OverrideFunctionWithDetour, 501 FunctionPrefixDetour); 502 #endif 503 504 TestIdentityFunctionMultiplePatching(kIdentityCodeWithMov, 505 OverrideFunctionWithHotPatch, 506 FunctionPrefixHotPatch); 507 508 TestIdentityFunctionMultiplePatching(kIdentityCodeWithPushPop, 509 OverrideFunctionWithTrampoline, 510 FunctionPrefixPadding); 511 } 512 513 TEST(Interception, OverrideFunctionTwice) { 514 uptr identity_address1; 515 LoadActiveCode(kIdentityTwice, &identity_address1); 516 uptr identity_address2 = identity_address1 + kIdentityTwiceOffset; 517 IdentityFunction identity1 = (IdentityFunction)identity_address1; 518 IdentityFunction identity2 = (IdentityFunction)identity_address2; 519 520 // Patch the two functions. 521 uptr real_identity_address = 0; 522 EXPECT_TRUE(OverrideFunction(identity_address1, 523 (uptr)&InterceptorFunction, 524 &real_identity_address)); 525 EXPECT_TRUE(OverrideFunction(identity_address2, 526 (uptr)&InterceptorFunction, 527 &real_identity_address)); 528 IdentityFunction real_identity = (IdentityFunction)real_identity_address; 529 InterceptedRealFunction = real_identity; 530 531 // Calling the redirected function. 532 InterceptorFunctionCalled = 0; 533 EXPECT_EQ(42, identity1(42)); 534 EXPECT_EQ(42, identity2(42)); 535 EXPECT_EQ(2, InterceptorFunctionCalled); 536 537 TestOnlyReleaseTrampolineRegions(); 538 } 539 540 template<class T> 541 static bool TestFunctionPatching( 542 const T &code, 543 TestOverrideFunction override, 544 FunctionPrefixKind prefix_kind = FunctionPrefixNone) { 545 uptr address; 546 LoadActiveCode(code, &address, prefix_kind); 547 uptr unused_real_address = 0; 548 bool result = override( 549 address, (uptr)&InterceptorFunction, &unused_real_address); 550 551 TestOnlyReleaseTrampolineRegions(); 552 return result; 553 } 554 555 TEST(Interception, PatchableFunction) { 556 TestOverrideFunction override = OverrideFunction; 557 // Test without function padding. 558 EXPECT_TRUE(TestFunctionPatching(kPatchableCode1, override)); 559 EXPECT_TRUE(TestFunctionPatching(kPatchableCode2, override)); 560 #if SANITIZER_WINDOWS64 561 EXPECT_FALSE(TestFunctionPatching(kPatchableCode3, override)); 562 #else 563 EXPECT_TRUE(TestFunctionPatching(kPatchableCode3, override)); 564 #endif 565 EXPECT_TRUE(TestFunctionPatching(kPatchableCode4, override)); 566 EXPECT_TRUE(TestFunctionPatching(kPatchableCode5, override)); 567 #if SANITIZER_WINDOWS64 568 EXPECT_TRUE(TestFunctionPatching(kLoadGlobalCode, override)); 569 #endif 570 571 EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode1, override)); 572 EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode2, override)); 573 EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode3, override)); 574 EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode4, override)); 575 EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode5, override)); 576 EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode6, override)); 577 } 578 579 #if !SANITIZER_WINDOWS64 580 TEST(Interception, PatchableFunctionWithDetour) { 581 TestOverrideFunction override = OverrideFunctionWithDetour; 582 // Without the prefix, no function can be detoured. 583 EXPECT_FALSE(TestFunctionPatching(kPatchableCode1, override)); 584 EXPECT_FALSE(TestFunctionPatching(kPatchableCode2, override)); 585 EXPECT_FALSE(TestFunctionPatching(kPatchableCode3, override)); 586 EXPECT_FALSE(TestFunctionPatching(kPatchableCode4, override)); 587 EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode1, override)); 588 EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode2, override)); 589 EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode3, override)); 590 EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode4, override)); 591 EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode5, override)); 592 EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode6, override)); 593 594 // With the prefix, all functions can be detoured. 595 FunctionPrefixKind prefix = FunctionPrefixDetour; 596 EXPECT_TRUE(TestFunctionPatching(kPatchableCode1, override, prefix)); 597 EXPECT_TRUE(TestFunctionPatching(kPatchableCode2, override, prefix)); 598 EXPECT_TRUE(TestFunctionPatching(kPatchableCode3, override, prefix)); 599 EXPECT_TRUE(TestFunctionPatching(kPatchableCode4, override, prefix)); 600 EXPECT_TRUE(TestFunctionPatching(kUnpatchableCode1, override, prefix)); 601 EXPECT_TRUE(TestFunctionPatching(kUnpatchableCode2, override, prefix)); 602 EXPECT_TRUE(TestFunctionPatching(kUnpatchableCode3, override, prefix)); 603 EXPECT_TRUE(TestFunctionPatching(kUnpatchableCode4, override, prefix)); 604 EXPECT_TRUE(TestFunctionPatching(kUnpatchableCode5, override, prefix)); 605 EXPECT_TRUE(TestFunctionPatching(kUnpatchableCode6, override, prefix)); 606 } 607 #endif // !SANITIZER_WINDOWS64 608 609 TEST(Interception, PatchableFunctionWithRedirectJump) { 610 TestOverrideFunction override = OverrideFunctionWithRedirectJump; 611 EXPECT_FALSE(TestFunctionPatching(kPatchableCode1, override)); 612 EXPECT_FALSE(TestFunctionPatching(kPatchableCode2, override)); 613 EXPECT_FALSE(TestFunctionPatching(kPatchableCode3, override)); 614 EXPECT_TRUE(TestFunctionPatching(kPatchableCode4, override)); 615 EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode1, override)); 616 EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode2, override)); 617 EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode3, override)); 618 EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode4, override)); 619 EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode5, override)); 620 EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode6, override)); 621 } 622 623 TEST(Interception, PatchableFunctionWithHotPatch) { 624 TestOverrideFunction override = OverrideFunctionWithHotPatch; 625 FunctionPrefixKind prefix = FunctionPrefixHotPatch; 626 627 EXPECT_TRUE(TestFunctionPatching(kPatchableCode1, override, prefix)); 628 EXPECT_FALSE(TestFunctionPatching(kPatchableCode2, override, prefix)); 629 EXPECT_FALSE(TestFunctionPatching(kPatchableCode3, override, prefix)); 630 EXPECT_FALSE(TestFunctionPatching(kPatchableCode4, override, prefix)); 631 #if SANITIZER_WINDOWS64 632 EXPECT_TRUE(TestFunctionPatching(kPatchableCode6, override, prefix)); 633 EXPECT_TRUE(TestFunctionPatching(kPatchableCode7, override, prefix)); 634 EXPECT_TRUE(TestFunctionPatching(kPatchableCode8, override, prefix)); 635 #endif 636 EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode1, override, prefix)); 637 EXPECT_TRUE(TestFunctionPatching(kUnpatchableCode2, override, prefix)); 638 EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode3, override, prefix)); 639 EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode4, override, prefix)); 640 EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode5, override, prefix)); 641 EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode6, override, prefix)); 642 } 643 644 TEST(Interception, PatchableFunctionWithTrampoline) { 645 TestOverrideFunction override = OverrideFunctionWithTrampoline; 646 FunctionPrefixKind prefix = FunctionPrefixPadding; 647 648 EXPECT_TRUE(TestFunctionPatching(kPatchableCode1, override, prefix)); 649 EXPECT_TRUE(TestFunctionPatching(kPatchableCode2, override, prefix)); 650 #if SANITIZER_WINDOWS64 651 EXPECT_FALSE(TestFunctionPatching(kPatchableCode3, override, prefix)); 652 EXPECT_TRUE(TestFunctionPatching(kPatchableCode9, override, prefix)); 653 EXPECT_TRUE(TestFunctionPatching(kPatchableCode10, override, prefix)); 654 EXPECT_TRUE(TestFunctionPatching(kPatchableCode11, override, prefix)); 655 EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode7, override, prefix)); 656 EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode8, override, prefix)); 657 EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode9, override, prefix)); 658 #else 659 EXPECT_TRUE(TestFunctionPatching(kPatchableCode3, override, prefix)); 660 #endif 661 EXPECT_FALSE(TestFunctionPatching(kPatchableCode4, override, prefix)); 662 663 EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode1, override, prefix)); 664 EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode2, override, prefix)); 665 EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode3, override, prefix)); 666 EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode4, override, prefix)); 667 EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode5, override, prefix)); 668 EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode6, override, prefix)); 669 } 670 671 TEST(Interception, PatchableFunctionPadding) { 672 TestOverrideFunction override = OverrideFunction; 673 FunctionPrefixKind prefix = FunctionPrefixPadding; 674 675 EXPECT_TRUE(TestFunctionPatching(kPatchableCode1, override, prefix)); 676 EXPECT_TRUE(TestFunctionPatching(kPatchableCode2, override, prefix)); 677 #if SANITIZER_WINDOWS64 678 EXPECT_FALSE(TestFunctionPatching(kPatchableCode3, override, prefix)); 679 #else 680 EXPECT_TRUE(TestFunctionPatching(kPatchableCode3, override, prefix)); 681 #endif 682 EXPECT_TRUE(TestFunctionPatching(kPatchableCode4, override, prefix)); 683 684 EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode1, override, prefix)); 685 EXPECT_TRUE(TestFunctionPatching(kUnpatchableCode2, override, prefix)); 686 EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode3, override, prefix)); 687 EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode4, override, prefix)); 688 EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode5, override, prefix)); 689 EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode6, override, prefix)); 690 } 691 692 TEST(Interception, EmptyExportTable) { 693 // We try to get a pointer to a function from an executable that doesn't 694 // export any symbol (empty export table). 695 uptr FunPtr = InternalGetProcAddress((void *)GetModuleHandleA(0), "example"); 696 EXPECT_EQ(0U, FunPtr); 697 } 698 699 } // namespace __interception 700 701 #endif // SANITIZER_WINDOWS 702 #endif // #if !SANITIZER_DEBUG 703