19642e337SNico Weber //===-- interception_win_test.cpp -----------------------------------------===//
29642e337SNico Weber //
39642e337SNico Weber // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
49642e337SNico Weber // See https://llvm.org/LICENSE.txt for license information.
59642e337SNico Weber // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
69642e337SNico Weber //
79642e337SNico Weber //===----------------------------------------------------------------------===//
89642e337SNico Weber //
99642e337SNico Weber // This file is a part of ThreadSanitizer/AddressSanitizer runtime.
109642e337SNico Weber // Tests for interception_win.h.
119642e337SNico Weber //
129642e337SNico Weber //===----------------------------------------------------------------------===//
139642e337SNico Weber #include "interception/interception.h"
149642e337SNico Weber 
159642e337SNico Weber #include "gtest/gtest.h"
169642e337SNico Weber 
179642e337SNico Weber // Too slow for debug build
189642e337SNico Weber #if !SANITIZER_DEBUG
199642e337SNico Weber #if SANITIZER_WINDOWS
209642e337SNico Weber 
219642e337SNico Weber #define WIN32_LEAN_AND_MEAN
229642e337SNico Weber #include <windows.h>
239642e337SNico Weber 
249642e337SNico Weber namespace __interception {
259642e337SNico Weber namespace {
269642e337SNico Weber 
279642e337SNico Weber enum FunctionPrefixKind {
289642e337SNico Weber   FunctionPrefixNone,
299642e337SNico Weber   FunctionPrefixPadding,
309642e337SNico Weber   FunctionPrefixHotPatch,
319642e337SNico Weber   FunctionPrefixDetour,
329642e337SNico Weber };
339642e337SNico Weber 
349642e337SNico Weber typedef bool (*TestOverrideFunction)(uptr, uptr, uptr*);
359642e337SNico Weber typedef int (*IdentityFunction)(int);
369642e337SNico Weber 
379642e337SNico Weber #if SANITIZER_WINDOWS64
389642e337SNico Weber 
399642e337SNico Weber const u8 kIdentityCodeWithPrologue[] = {
409642e337SNico Weber     0x55,                   // push        rbp
419642e337SNico Weber     0x48, 0x89, 0xE5,       // mov         rbp,rsp
429642e337SNico Weber     0x8B, 0xC1,             // mov         eax,ecx
439642e337SNico Weber     0x5D,                   // pop         rbp
449642e337SNico Weber     0xC3,                   // ret
459642e337SNico Weber };
469642e337SNico Weber 
479642e337SNico Weber const u8 kIdentityCodeWithPushPop[] = {
489642e337SNico Weber     0x55,                   // push        rbp
499642e337SNico Weber     0x48, 0x89, 0xE5,       // mov         rbp,rsp
509642e337SNico Weber     0x53,                   // push        rbx
519642e337SNico Weber     0x50,                   // push        rax
529642e337SNico Weber     0x58,                   // pop         rax
539642e337SNico Weber     0x8B, 0xC1,             // mov         rax,rcx
549642e337SNico Weber     0x5B,                   // pop         rbx
559642e337SNico Weber     0x5D,                   // pop         rbp
569642e337SNico Weber     0xC3,                   // ret
579642e337SNico Weber };
589642e337SNico Weber 
599642e337SNico Weber const u8 kIdentityTwiceOffset = 16;
609642e337SNico Weber const u8 kIdentityTwice[] = {
619642e337SNico Weber     0x55,                   // push        rbp
629642e337SNico Weber     0x48, 0x89, 0xE5,       // mov         rbp,rsp
639642e337SNico Weber     0x8B, 0xC1,             // mov         eax,ecx
649642e337SNico Weber     0x5D,                   // pop         rbp
659642e337SNico Weber     0xC3,                   // ret
669642e337SNico Weber     0x90, 0x90, 0x90, 0x90,
679642e337SNico Weber     0x90, 0x90, 0x90, 0x90,
689642e337SNico Weber     0x55,                   // push        rbp
699642e337SNico Weber     0x48, 0x89, 0xE5,       // mov         rbp,rsp
709642e337SNico Weber     0x8B, 0xC1,             // mov         eax,ecx
719642e337SNico Weber     0x5D,                   // pop         rbp
729642e337SNico Weber     0xC3,                   // ret
739642e337SNico Weber };
749642e337SNico Weber 
759642e337SNico Weber const u8 kIdentityCodeWithMov[] = {
769642e337SNico Weber     0x89, 0xC8,             // mov         eax, ecx
779642e337SNico Weber     0xC3,                   // ret
789642e337SNico Weber };
799642e337SNico Weber 
809642e337SNico Weber const u8 kIdentityCodeWithJump[] = {
819642e337SNico Weber     0xE9, 0x04, 0x00, 0x00,
829642e337SNico Weber     0x00,                   // jmp + 4
839642e337SNico Weber     0xCC, 0xCC, 0xCC, 0xCC,
849642e337SNico Weber     0x89, 0xC8,             // mov         eax, ecx
859642e337SNico Weber     0xC3,                   // ret
869642e337SNico Weber };
879642e337SNico Weber 
889642e337SNico Weber #else
899642e337SNico Weber 
909642e337SNico Weber const u8 kIdentityCodeWithPrologue[] = {
919642e337SNico Weber     0x55,                   // push        ebp
929642e337SNico Weber     0x8B, 0xEC,             // mov         ebp,esp
939642e337SNico Weber     0x8B, 0x45, 0x08,       // mov         eax,dword ptr [ebp + 8]
949642e337SNico Weber     0x5D,                   // pop         ebp
959642e337SNico Weber     0xC3,                   // ret
969642e337SNico Weber };
979642e337SNico Weber 
989642e337SNico Weber const u8 kIdentityCodeWithPushPop[] = {
999642e337SNico Weber     0x55,                   // push        ebp
1009642e337SNico Weber     0x8B, 0xEC,             // mov         ebp,esp
1019642e337SNico Weber     0x53,                   // push        ebx
1029642e337SNico Weber     0x50,                   // push        eax
1039642e337SNico Weber     0x58,                   // pop         eax
1049642e337SNico Weber     0x8B, 0x45, 0x08,       // mov         eax,dword ptr [ebp + 8]
1059642e337SNico Weber     0x5B,                   // pop         ebx
1069642e337SNico Weber     0x5D,                   // pop         ebp
1079642e337SNico Weber     0xC3,                   // ret
1089642e337SNico Weber };
1099642e337SNico Weber 
1109642e337SNico Weber const u8 kIdentityTwiceOffset = 8;
1119642e337SNico Weber const u8 kIdentityTwice[] = {
1129642e337SNico Weber     0x55,                   // push        ebp
1139642e337SNico Weber     0x8B, 0xEC,             // mov         ebp,esp
1149642e337SNico Weber     0x8B, 0x45, 0x08,       // mov         eax,dword ptr [ebp + 8]
1159642e337SNico Weber     0x5D,                   // pop         ebp
1169642e337SNico Weber     0xC3,                   // ret
1179642e337SNico Weber     0x55,                   // push        ebp
1189642e337SNico Weber     0x8B, 0xEC,             // mov         ebp,esp
1199642e337SNico Weber     0x8B, 0x45, 0x08,       // mov         eax,dword ptr [ebp + 8]
1209642e337SNico Weber     0x5D,                   // pop         ebp
1219642e337SNico Weber     0xC3,                   // ret
1229642e337SNico Weber };
1239642e337SNico Weber 
1249642e337SNico Weber const u8 kIdentityCodeWithMov[] = {
1259642e337SNico Weber     0x8B, 0x44, 0x24, 0x04, // mov         eax,dword ptr [esp + 4]
1269642e337SNico Weber     0xC3,                   // ret
1279642e337SNico Weber };
1289642e337SNico Weber 
1299642e337SNico Weber const u8 kIdentityCodeWithJump[] = {
1309642e337SNico Weber     0xE9, 0x04, 0x00, 0x00,
1319642e337SNico Weber     0x00,                   // jmp + 4
1329642e337SNico Weber     0xCC, 0xCC, 0xCC, 0xCC,
1339642e337SNico Weber     0x8B, 0x44, 0x24, 0x04, // mov         eax,dword ptr [esp + 4]
1349642e337SNico Weber     0xC3,                   // ret
1359642e337SNico Weber };
1369642e337SNico Weber 
1379642e337SNico Weber #endif
1389642e337SNico Weber 
1399642e337SNico Weber const u8 kPatchableCode1[] = {
1409642e337SNico Weber     0xB8, 0x4B, 0x00, 0x00, 0x00,   // mov eax,4B
1419642e337SNico Weber     0x33, 0xC9,                     // xor ecx,ecx
1429642e337SNico Weber     0xC3,                           // ret
1439642e337SNico Weber };
1449642e337SNico Weber 
1459642e337SNico Weber const u8 kPatchableCode2[] = {
1469642e337SNico Weber     0x55,                           // push ebp
1479642e337SNico Weber     0x8B, 0xEC,                     // mov ebp,esp
1489642e337SNico Weber     0x33, 0xC0,                     // xor eax,eax
1499642e337SNico Weber     0x5D,                           // pop ebp
1509642e337SNico Weber     0xC3,                           // ret
1519642e337SNico Weber };
1529642e337SNico Weber 
1539642e337SNico Weber const u8 kPatchableCode3[] = {
1549642e337SNico Weber     0x55,                           // push ebp
1559642e337SNico Weber     0x8B, 0xEC,                     // mov ebp,esp
1569642e337SNico Weber     0x6A, 0x00,                     // push 0
1579642e337SNico Weber     0xE8, 0x3D, 0xFF, 0xFF, 0xFF,   // call <func>
1589642e337SNico Weber };
1599642e337SNico Weber 
1609642e337SNico Weber const u8 kPatchableCode4[] = {
1619642e337SNico Weber     0xE9, 0xCC, 0xCC, 0xCC, 0xCC,   // jmp <label>
1629642e337SNico Weber     0x90, 0x90, 0x90, 0x90,
1639642e337SNico Weber };
1649642e337SNico Weber 
1659642e337SNico Weber const u8 kPatchableCode5[] = {
1669642e337SNico Weber     0x55,                                      // push    ebp
1679642e337SNico Weber     0x8b, 0xec,                                // mov     ebp,esp
1689642e337SNico Weber     0x8d, 0xa4, 0x24, 0x30, 0xfd, 0xff, 0xff,  // lea     esp,[esp-2D0h]
1699642e337SNico Weber     0x54,                                      // push    esp
1709642e337SNico Weber };
1719642e337SNico Weber 
1729642e337SNico Weber #if SANITIZER_WINDOWS64
1739642e337SNico Weber u8 kLoadGlobalCode[] = {
1749642e337SNico Weber   0x8B, 0x05, 0x00, 0x00, 0x00, 0x00, // mov    eax [rip + global]
1759642e337SNico Weber   0xC3,                               // ret
1769642e337SNico Weber };
1779642e337SNico Weber #endif
1789642e337SNico Weber 
1799642e337SNico Weber const u8 kUnpatchableCode1[] = {
1809642e337SNico Weber     0xC3,                           // ret
1819642e337SNico Weber };
1829642e337SNico Weber 
1839642e337SNico Weber const u8 kUnpatchableCode2[] = {
1849642e337SNico Weber     0x33, 0xC9,                     // xor ecx,ecx
1859642e337SNico Weber     0xC3,                           // ret
1869642e337SNico Weber };
1879642e337SNico Weber 
1889642e337SNico Weber const u8 kUnpatchableCode3[] = {
1899642e337SNico Weber     0x75, 0xCC,                     // jne <label>
1909642e337SNico Weber     0x33, 0xC9,                     // xor ecx,ecx
1919642e337SNico Weber     0xC3,                           // ret
1929642e337SNico Weber };
1939642e337SNico Weber 
1949642e337SNico Weber const u8 kUnpatchableCode4[] = {
1959642e337SNico Weber     0x74, 0xCC,                     // jne <label>
1969642e337SNico Weber     0x33, 0xC9,                     // xor ecx,ecx
1979642e337SNico Weber     0xC3,                           // ret
1989642e337SNico Weber };
1999642e337SNico Weber 
2009642e337SNico Weber const u8 kUnpatchableCode5[] = {
2019642e337SNico Weber     0xEB, 0x02,                     // jmp <label>
2029642e337SNico Weber     0x33, 0xC9,                     // xor ecx,ecx
2039642e337SNico Weber     0xC3,                           // ret
2049642e337SNico Weber };
2059642e337SNico Weber 
2069642e337SNico Weber const u8 kUnpatchableCode6[] = {
2079642e337SNico Weber     0xE8, 0xCC, 0xCC, 0xCC, 0xCC,   // call <func>
2089642e337SNico Weber     0x90, 0x90, 0x90, 0x90,
2099642e337SNico Weber };
2109642e337SNico Weber 
211*22ea0ceaSToshihito Kikuchi const u8 kUnpatchableCode7[] = {
212*22ea0ceaSToshihito Kikuchi     0x33, 0xc0,                     // xor     eax,eax
213*22ea0ceaSToshihito Kikuchi     0x48, 0x85, 0xd2,               // test    rdx,rdx
214*22ea0ceaSToshihito Kikuchi     0x74, 0x10,                     // je      +16  (unpatchable)
215*22ea0ceaSToshihito Kikuchi };
216*22ea0ceaSToshihito Kikuchi 
217*22ea0ceaSToshihito Kikuchi const u8 kUnpatchableCode8[] = {
218*22ea0ceaSToshihito Kikuchi     0x48, 0x8b, 0xc1,               // mov     rax,rcx
219*22ea0ceaSToshihito Kikuchi     0x0f, 0xb7, 0x10,               // movzx   edx,word ptr [rax]
220*22ea0ceaSToshihito Kikuchi     0x48, 0x83, 0xc0, 0x02,         // add     rax,2
221*22ea0ceaSToshihito Kikuchi     0x66, 0x85, 0xd2,               // test    dx,dx
222*22ea0ceaSToshihito Kikuchi     0x75, 0xf4,                     // jne     -12  (unpatchable)
223*22ea0ceaSToshihito Kikuchi };
224*22ea0ceaSToshihito Kikuchi 
225*22ea0ceaSToshihito Kikuchi const u8 kUnpatchableCode9[] = {
226*22ea0ceaSToshihito Kikuchi     0x4c, 0x8b, 0xc1,               // mov     r8,rcx
227*22ea0ceaSToshihito Kikuchi     0x8a, 0x01,                     // mov     al,byte ptr [rcx]
228*22ea0ceaSToshihito Kikuchi     0x48, 0xff, 0xc1,               // inc     rcx
229*22ea0ceaSToshihito Kikuchi     0x84, 0xc0,                     // test    al,al
230*22ea0ceaSToshihito Kikuchi     0x75, 0xf7,                     // jne     -9  (unpatchable)
231*22ea0ceaSToshihito Kikuchi };
232*22ea0ceaSToshihito Kikuchi 
2339642e337SNico Weber const u8 kPatchableCode6[] = {
2349642e337SNico Weber     0x48, 0x89, 0x54, 0x24, 0xBB, // mov QWORD PTR [rsp + 0xBB], rdx
2359642e337SNico Weber     0x33, 0xC9,                   // xor ecx,ecx
2369642e337SNico Weber     0xC3,                         // ret
2379642e337SNico Weber };
2389642e337SNico Weber 
2399642e337SNico Weber const u8 kPatchableCode7[] = {
2409642e337SNico Weber     0x4c, 0x89, 0x4c, 0x24, 0xBB,  // mov QWORD PTR [rsp + 0xBB], r9
2419642e337SNico Weber     0x33, 0xC9,                   // xor ecx,ecx
2429642e337SNico Weber     0xC3,                         // ret
2439642e337SNico Weber };
2449642e337SNico Weber 
2459642e337SNico Weber const u8 kPatchableCode8[] = {
2469642e337SNico Weber     0x4c, 0x89, 0x44, 0x24, 0xBB, // mov QWORD PTR [rsp + 0xBB], r8
2479642e337SNico Weber     0x33, 0xC9,                   // xor ecx,ecx
2489642e337SNico Weber     0xC3,                         // ret
2499642e337SNico Weber };
2509642e337SNico Weber 
251*22ea0ceaSToshihito Kikuchi const u8 kPatchableCode9[] = {
252*22ea0ceaSToshihito Kikuchi     0x8a, 0x01,                     // al,byte ptr [rcx]
253*22ea0ceaSToshihito Kikuchi     0x45, 0x33, 0xc0,               // xor     r8d,r8d
254*22ea0ceaSToshihito Kikuchi     0x84, 0xc0,                     // test    al,al
255*22ea0ceaSToshihito Kikuchi };
256*22ea0ceaSToshihito Kikuchi 
257*22ea0ceaSToshihito Kikuchi const u8 kPatchableCode10[] = {
258*22ea0ceaSToshihito Kikuchi     0x45, 0x33, 0xc0,               // xor     r8d,r8d
259*22ea0ceaSToshihito Kikuchi     0x41, 0x8b, 0xc0,               // mov     eax,r8d
260*22ea0ceaSToshihito Kikuchi     0x48, 0x85, 0xd2,               // test    rdx,rdx
261*22ea0ceaSToshihito Kikuchi };
262*22ea0ceaSToshihito Kikuchi 
263*22ea0ceaSToshihito Kikuchi const u8 kPatchableCode11[] = {
264*22ea0ceaSToshihito Kikuchi     0x48, 0x83, 0xec, 0x38,         // sub     rsp,38h
265*22ea0ceaSToshihito Kikuchi     0x83, 0x64, 0x24, 0x28, 0x00,   // and     dword ptr [rsp+28h],0
266*22ea0ceaSToshihito Kikuchi };
267*22ea0ceaSToshihito Kikuchi 
2689642e337SNico Weber // A buffer holding the dynamically generated code under test.
2699642e337SNico Weber u8* ActiveCode;
2709642e337SNico Weber const size_t ActiveCodeLength = 4096;
2719642e337SNico Weber 
2729642e337SNico Weber int InterceptorFunction(int x);
2739642e337SNico Weber 
2749642e337SNico Weber /// Allocate code memory more than 2GB away from Base.
AllocateCode2GBAway(u8 * Base)2759642e337SNico Weber u8 *AllocateCode2GBAway(u8 *Base) {
2769642e337SNico Weber   // Find a 64K aligned location after Base plus 2GB.
2779642e337SNico Weber   size_t TwoGB = 0x80000000;
2789642e337SNico Weber   size_t AllocGranularity = 0x10000;
2799642e337SNico Weber   Base = (u8 *)((((uptr)Base + TwoGB + AllocGranularity)) & ~(AllocGranularity - 1));
2809642e337SNico Weber 
2819642e337SNico Weber   // Check if that location is free, and if not, loop over regions until we find
2829642e337SNico Weber   // one that is.
2839642e337SNico Weber   MEMORY_BASIC_INFORMATION mbi = {};
2849642e337SNico Weber   while (sizeof(mbi) == VirtualQuery(Base, &mbi, sizeof(mbi))) {
2859642e337SNico Weber     if (mbi.State & MEM_FREE) break;
2869642e337SNico Weber     Base += mbi.RegionSize;
2879642e337SNico Weber   }
2889642e337SNico Weber 
2899642e337SNico Weber   // Allocate one RWX page at the free location.
2909642e337SNico Weber   return (u8 *)::VirtualAlloc(Base, ActiveCodeLength, MEM_COMMIT | MEM_RESERVE,
2919642e337SNico Weber                               PAGE_EXECUTE_READWRITE);
2929642e337SNico Weber }
2939642e337SNico Weber 
2949642e337SNico Weber template<class T>
LoadActiveCode(const T & code,uptr * entry_point,FunctionPrefixKind prefix_kind=FunctionPrefixNone)2959642e337SNico Weber static void LoadActiveCode(
2969642e337SNico Weber     const T &code,
2979642e337SNico Weber     uptr *entry_point,
2989642e337SNico Weber     FunctionPrefixKind prefix_kind = FunctionPrefixNone) {
2999642e337SNico Weber   if (ActiveCode == nullptr) {
3009642e337SNico Weber     ActiveCode = AllocateCode2GBAway((u8*)&InterceptorFunction);
3019642e337SNico Weber     ASSERT_NE(ActiveCode, nullptr) << "failed to allocate RWX memory 2GB away";
3029642e337SNico Weber   }
3039642e337SNico Weber 
3049642e337SNico Weber   size_t position = 0;
3059642e337SNico Weber 
3069642e337SNico Weber   // Add padding to avoid memory violation when scanning the prefix.
3079642e337SNico Weber   for (int i = 0; i < 16; ++i)
3089642e337SNico Weber     ActiveCode[position++] = 0xC3;  // Instruction 'ret'.
3099642e337SNico Weber 
3109642e337SNico Weber   // Add function padding.
3119642e337SNico Weber   size_t padding = 0;
3129642e337SNico Weber   if (prefix_kind == FunctionPrefixPadding)
3139642e337SNico Weber     padding = 16;
3149642e337SNico Weber   else if (prefix_kind == FunctionPrefixDetour ||
3159642e337SNico Weber            prefix_kind == FunctionPrefixHotPatch)
3169642e337SNico Weber     padding = FIRST_32_SECOND_64(5, 6);
3179642e337SNico Weber   // Insert |padding| instructions 'nop'.
3189642e337SNico Weber   for (size_t i = 0; i < padding; ++i)
3199642e337SNico Weber     ActiveCode[position++] = 0x90;
3209642e337SNico Weber 
3219642e337SNico Weber   // Keep track of the entry point.
3229642e337SNico Weber   *entry_point = (uptr)&ActiveCode[position];
3239642e337SNico Weber 
3249642e337SNico Weber   // Add the detour instruction (i.e. mov edi, edi)
3259642e337SNico Weber   if (prefix_kind == FunctionPrefixDetour) {
3269642e337SNico Weber #if SANITIZER_WINDOWS64
3279642e337SNico Weber     // Note that "mov edi,edi" is NOP in 32-bit only, in 64-bit it clears
3289642e337SNico Weber     // higher bits of RDI.
3299642e337SNico Weber     // Use 66,90H as NOP for Windows64.
3309642e337SNico Weber     ActiveCode[position++] = 0x66;
3319642e337SNico Weber     ActiveCode[position++] = 0x90;
3329642e337SNico Weber #else
3339642e337SNico Weber     // mov edi,edi.
3349642e337SNico Weber     ActiveCode[position++] = 0x8B;
3359642e337SNico Weber     ActiveCode[position++] = 0xFF;
3369642e337SNico Weber #endif
3379642e337SNico Weber 
3389642e337SNico Weber   }
3399642e337SNico Weber 
3409642e337SNico Weber   // Copy the function body.
3419642e337SNico Weber   for (size_t i = 0; i < sizeof(T); ++i)
3429642e337SNico Weber     ActiveCode[position++] = code[i];
3439642e337SNico Weber }
3449642e337SNico Weber 
3459642e337SNico Weber int InterceptorFunctionCalled;
3469642e337SNico Weber IdentityFunction InterceptedRealFunction;
3479642e337SNico Weber 
InterceptorFunction(int x)3489642e337SNico Weber int InterceptorFunction(int x) {
3499642e337SNico Weber   ++InterceptorFunctionCalled;
3509642e337SNico Weber   return InterceptedRealFunction(x);
3519642e337SNico Weber }
3529642e337SNico Weber 
3539642e337SNico Weber }  // namespace
3549642e337SNico Weber 
3559642e337SNico Weber // Tests for interception_win.h
TEST(Interception,InternalGetProcAddress)3569642e337SNico Weber TEST(Interception, InternalGetProcAddress) {
3579642e337SNico Weber   HMODULE ntdll_handle = ::GetModuleHandle("ntdll");
3589642e337SNico Weber   ASSERT_NE(nullptr, ntdll_handle);
3599642e337SNico Weber   uptr DbgPrint_expected = (uptr)::GetProcAddress(ntdll_handle, "DbgPrint");
3609642e337SNico Weber   uptr isdigit_expected = (uptr)::GetProcAddress(ntdll_handle, "isdigit");
3619642e337SNico Weber   uptr DbgPrint_adddress = InternalGetProcAddress(ntdll_handle, "DbgPrint");
3629642e337SNico Weber   uptr isdigit_address = InternalGetProcAddress(ntdll_handle, "isdigit");
3639642e337SNico Weber 
3649642e337SNico Weber   EXPECT_EQ(DbgPrint_expected, DbgPrint_adddress);
3659642e337SNico Weber   EXPECT_EQ(isdigit_expected, isdigit_address);
3669642e337SNico Weber   EXPECT_NE(DbgPrint_adddress, isdigit_address);
3679642e337SNico Weber }
3689642e337SNico Weber 
3699642e337SNico Weber template<class T>
TestIdentityFunctionPatching(const T & code,TestOverrideFunction override,FunctionPrefixKind prefix_kind=FunctionPrefixNone)3709642e337SNico Weber static void TestIdentityFunctionPatching(
3719642e337SNico Weber     const T &code,
3729642e337SNico Weber     TestOverrideFunction override,
3739642e337SNico Weber     FunctionPrefixKind prefix_kind = FunctionPrefixNone) {
3749642e337SNico Weber   uptr identity_address;
3759642e337SNico Weber   LoadActiveCode(code, &identity_address, prefix_kind);
3769642e337SNico Weber   IdentityFunction identity = (IdentityFunction)identity_address;
3779642e337SNico Weber 
3789642e337SNico Weber   // Validate behavior before dynamic patching.
3799642e337SNico Weber   InterceptorFunctionCalled = 0;
3809642e337SNico Weber   EXPECT_EQ(0, identity(0));
3819642e337SNico Weber   EXPECT_EQ(42, identity(42));
3829642e337SNico Weber   EXPECT_EQ(0, InterceptorFunctionCalled);
3839642e337SNico Weber 
3849642e337SNico Weber   // Patch the function.
3859642e337SNico Weber   uptr real_identity_address = 0;
3869642e337SNico Weber   bool success = override(identity_address,
3879642e337SNico Weber                          (uptr)&InterceptorFunction,
3889642e337SNico Weber                          &real_identity_address);
3899642e337SNico Weber   EXPECT_TRUE(success);
3909642e337SNico Weber   EXPECT_NE(0U, real_identity_address);
3919642e337SNico Weber   IdentityFunction real_identity = (IdentityFunction)real_identity_address;
3929642e337SNico Weber   InterceptedRealFunction = real_identity;
3939642e337SNico Weber 
3949642e337SNico Weber   // Don't run tests if hooking failed or the real function is not valid.
3959642e337SNico Weber   if (!success || !real_identity_address)
3969642e337SNico Weber     return;
3979642e337SNico Weber 
3989642e337SNico Weber   // Calling the redirected function.
3999642e337SNico Weber   InterceptorFunctionCalled = 0;
4009642e337SNico Weber   EXPECT_EQ(0, identity(0));
4019642e337SNico Weber   EXPECT_EQ(42, identity(42));
4029642e337SNico Weber   EXPECT_EQ(2, InterceptorFunctionCalled);
4039642e337SNico Weber 
4049642e337SNico Weber   // Calling the real function.
4059642e337SNico Weber   InterceptorFunctionCalled = 0;
4069642e337SNico Weber   EXPECT_EQ(0, real_identity(0));
4079642e337SNico Weber   EXPECT_EQ(42, real_identity(42));
4089642e337SNico Weber   EXPECT_EQ(0, InterceptorFunctionCalled);
4099642e337SNico Weber 
4109642e337SNico Weber   TestOnlyReleaseTrampolineRegions();
4119642e337SNico Weber }
4129642e337SNico Weber 
4139642e337SNico Weber #if !SANITIZER_WINDOWS64
TEST(Interception,OverrideFunctionWithDetour)4149642e337SNico Weber TEST(Interception, OverrideFunctionWithDetour) {
4159642e337SNico Weber   TestOverrideFunction override = OverrideFunctionWithDetour;
4169642e337SNico Weber   FunctionPrefixKind prefix = FunctionPrefixDetour;
4179642e337SNico Weber   TestIdentityFunctionPatching(kIdentityCodeWithPrologue, override, prefix);
4189642e337SNico Weber   TestIdentityFunctionPatching(kIdentityCodeWithPushPop, override, prefix);
4199642e337SNico Weber   TestIdentityFunctionPatching(kIdentityCodeWithMov, override, prefix);
4209642e337SNico Weber   TestIdentityFunctionPatching(kIdentityCodeWithJump, override, prefix);
4219642e337SNico Weber }
4229642e337SNico Weber #endif  // !SANITIZER_WINDOWS64
4239642e337SNico Weber 
TEST(Interception,OverrideFunctionWithRedirectJump)4249642e337SNico Weber TEST(Interception, OverrideFunctionWithRedirectJump) {
4259642e337SNico Weber   TestOverrideFunction override = OverrideFunctionWithRedirectJump;
4269642e337SNico Weber   TestIdentityFunctionPatching(kIdentityCodeWithJump, override);
4279642e337SNico Weber }
4289642e337SNico Weber 
TEST(Interception,OverrideFunctionWithHotPatch)4299642e337SNico Weber TEST(Interception, OverrideFunctionWithHotPatch) {
4309642e337SNico Weber   TestOverrideFunction override = OverrideFunctionWithHotPatch;
4319642e337SNico Weber   FunctionPrefixKind prefix = FunctionPrefixHotPatch;
4329642e337SNico Weber   TestIdentityFunctionPatching(kIdentityCodeWithMov, override, prefix);
4339642e337SNico Weber }
4349642e337SNico Weber 
TEST(Interception,OverrideFunctionWithTrampoline)4359642e337SNico Weber TEST(Interception, OverrideFunctionWithTrampoline) {
4369642e337SNico Weber   TestOverrideFunction override = OverrideFunctionWithTrampoline;
4379642e337SNico Weber   FunctionPrefixKind prefix = FunctionPrefixNone;
4389642e337SNico Weber   TestIdentityFunctionPatching(kIdentityCodeWithPrologue, override, prefix);
4399642e337SNico Weber   TestIdentityFunctionPatching(kIdentityCodeWithPushPop, override, prefix);
4409642e337SNico Weber 
4419642e337SNico Weber   prefix = FunctionPrefixPadding;
4429642e337SNico Weber   TestIdentityFunctionPatching(kIdentityCodeWithPrologue, override, prefix);
4439642e337SNico Weber   TestIdentityFunctionPatching(kIdentityCodeWithPushPop, override, prefix);
4449642e337SNico Weber }
4459642e337SNico Weber 
TEST(Interception,OverrideFunction)4469642e337SNico Weber TEST(Interception, OverrideFunction) {
4479642e337SNico Weber   TestOverrideFunction override = OverrideFunction;
4489642e337SNico Weber   FunctionPrefixKind prefix = FunctionPrefixNone;
4499642e337SNico Weber   TestIdentityFunctionPatching(kIdentityCodeWithPrologue, override, prefix);
4509642e337SNico Weber   TestIdentityFunctionPatching(kIdentityCodeWithPushPop, override, prefix);
4519642e337SNico Weber   TestIdentityFunctionPatching(kIdentityCodeWithJump, override, prefix);
4529642e337SNico Weber 
4539642e337SNico Weber   prefix = FunctionPrefixPadding;
4549642e337SNico Weber   TestIdentityFunctionPatching(kIdentityCodeWithPrologue, override, prefix);
4559642e337SNico Weber   TestIdentityFunctionPatching(kIdentityCodeWithPushPop, override, prefix);
4569642e337SNico Weber   TestIdentityFunctionPatching(kIdentityCodeWithMov, override, prefix);
4579642e337SNico Weber   TestIdentityFunctionPatching(kIdentityCodeWithJump, override, prefix);
4589642e337SNico Weber 
4599642e337SNico Weber   prefix = FunctionPrefixHotPatch;
4609642e337SNico Weber   TestIdentityFunctionPatching(kIdentityCodeWithPrologue, override, prefix);
4619642e337SNico Weber   TestIdentityFunctionPatching(kIdentityCodeWithPushPop, override, prefix);
4629642e337SNico Weber   TestIdentityFunctionPatching(kIdentityCodeWithMov, override, prefix);
4639642e337SNico Weber   TestIdentityFunctionPatching(kIdentityCodeWithJump, override, prefix);
4649642e337SNico Weber 
4659642e337SNico Weber   prefix = FunctionPrefixDetour;
4669642e337SNico Weber   TestIdentityFunctionPatching(kIdentityCodeWithPrologue, override, prefix);
4679642e337SNico Weber   TestIdentityFunctionPatching(kIdentityCodeWithPushPop, override, prefix);
4689642e337SNico Weber   TestIdentityFunctionPatching(kIdentityCodeWithMov, override, prefix);
4699642e337SNico Weber   TestIdentityFunctionPatching(kIdentityCodeWithJump, override, prefix);
4709642e337SNico Weber }
4719642e337SNico Weber 
4729642e337SNico Weber template<class T>
TestIdentityFunctionMultiplePatching(const T & code,TestOverrideFunction override,FunctionPrefixKind prefix_kind=FunctionPrefixNone)4739642e337SNico Weber static void TestIdentityFunctionMultiplePatching(
4749642e337SNico Weber     const T &code,
4759642e337SNico Weber     TestOverrideFunction override,
4769642e337SNico Weber     FunctionPrefixKind prefix_kind = FunctionPrefixNone) {
4779642e337SNico Weber   uptr identity_address;
4789642e337SNico Weber   LoadActiveCode(code, &identity_address, prefix_kind);
4799642e337SNico Weber 
4809642e337SNico Weber   // Patch the function.
4819642e337SNico Weber   uptr real_identity_address = 0;
4829642e337SNico Weber   bool success = override(identity_address,
4839642e337SNico Weber                           (uptr)&InterceptorFunction,
4849642e337SNico Weber                           &real_identity_address);
4859642e337SNico Weber   EXPECT_TRUE(success);
4869642e337SNico Weber   EXPECT_NE(0U, real_identity_address);
4879642e337SNico Weber 
4889642e337SNico Weber   // Re-patching the function should not work.
4899642e337SNico Weber   success = override(identity_address,
4909642e337SNico Weber                      (uptr)&InterceptorFunction,
4919642e337SNico Weber                      &real_identity_address);
4929642e337SNico Weber   EXPECT_FALSE(success);
4939642e337SNico Weber 
4949642e337SNico Weber   TestOnlyReleaseTrampolineRegions();
4959642e337SNico Weber }
4969642e337SNico Weber 
TEST(Interception,OverrideFunctionMultiplePatchingIsFailing)4979642e337SNico Weber TEST(Interception, OverrideFunctionMultiplePatchingIsFailing) {
4989642e337SNico Weber #if !SANITIZER_WINDOWS64
4999642e337SNico Weber   TestIdentityFunctionMultiplePatching(kIdentityCodeWithPrologue,
5009642e337SNico Weber                                        OverrideFunctionWithDetour,
5019642e337SNico Weber                                        FunctionPrefixDetour);
5029642e337SNico Weber #endif
5039642e337SNico Weber 
5049642e337SNico Weber   TestIdentityFunctionMultiplePatching(kIdentityCodeWithMov,
5059642e337SNico Weber                                        OverrideFunctionWithHotPatch,
5069642e337SNico Weber                                        FunctionPrefixHotPatch);
5079642e337SNico Weber 
5089642e337SNico Weber   TestIdentityFunctionMultiplePatching(kIdentityCodeWithPushPop,
5099642e337SNico Weber                                        OverrideFunctionWithTrampoline,
5109642e337SNico Weber                                        FunctionPrefixPadding);
5119642e337SNico Weber }
5129642e337SNico Weber 
TEST(Interception,OverrideFunctionTwice)5139642e337SNico Weber TEST(Interception, OverrideFunctionTwice) {
5149642e337SNico Weber   uptr identity_address1;
5159642e337SNico Weber   LoadActiveCode(kIdentityTwice, &identity_address1);
5169642e337SNico Weber   uptr identity_address2 = identity_address1 + kIdentityTwiceOffset;
5179642e337SNico Weber   IdentityFunction identity1 = (IdentityFunction)identity_address1;
5189642e337SNico Weber   IdentityFunction identity2 = (IdentityFunction)identity_address2;
5199642e337SNico Weber 
5209642e337SNico Weber   // Patch the two functions.
5219642e337SNico Weber   uptr real_identity_address = 0;
5229642e337SNico Weber   EXPECT_TRUE(OverrideFunction(identity_address1,
5239642e337SNico Weber                                (uptr)&InterceptorFunction,
5249642e337SNico Weber                                &real_identity_address));
5259642e337SNico Weber   EXPECT_TRUE(OverrideFunction(identity_address2,
5269642e337SNico Weber                                (uptr)&InterceptorFunction,
5279642e337SNico Weber                                &real_identity_address));
5289642e337SNico Weber   IdentityFunction real_identity = (IdentityFunction)real_identity_address;
5299642e337SNico Weber   InterceptedRealFunction = real_identity;
5309642e337SNico Weber 
5319642e337SNico Weber   // Calling the redirected function.
5329642e337SNico Weber   InterceptorFunctionCalled = 0;
5339642e337SNico Weber   EXPECT_EQ(42, identity1(42));
5349642e337SNico Weber   EXPECT_EQ(42, identity2(42));
5359642e337SNico Weber   EXPECT_EQ(2, InterceptorFunctionCalled);
5369642e337SNico Weber 
5379642e337SNico Weber   TestOnlyReleaseTrampolineRegions();
5389642e337SNico Weber }
5399642e337SNico Weber 
5409642e337SNico Weber template<class T>
TestFunctionPatching(const T & code,TestOverrideFunction override,FunctionPrefixKind prefix_kind=FunctionPrefixNone)5419642e337SNico Weber static bool TestFunctionPatching(
5429642e337SNico Weber     const T &code,
5439642e337SNico Weber     TestOverrideFunction override,
5449642e337SNico Weber     FunctionPrefixKind prefix_kind = FunctionPrefixNone) {
5459642e337SNico Weber   uptr address;
5469642e337SNico Weber   LoadActiveCode(code, &address, prefix_kind);
5479642e337SNico Weber   uptr unused_real_address = 0;
5489642e337SNico Weber   bool result = override(
5499642e337SNico Weber       address, (uptr)&InterceptorFunction, &unused_real_address);
5509642e337SNico Weber 
5519642e337SNico Weber   TestOnlyReleaseTrampolineRegions();
5529642e337SNico Weber   return result;
5539642e337SNico Weber }
5549642e337SNico Weber 
TEST(Interception,PatchableFunction)5559642e337SNico Weber TEST(Interception, PatchableFunction) {
5569642e337SNico Weber   TestOverrideFunction override = OverrideFunction;
5579642e337SNico Weber   // Test without function padding.
5589642e337SNico Weber   EXPECT_TRUE(TestFunctionPatching(kPatchableCode1, override));
5599642e337SNico Weber   EXPECT_TRUE(TestFunctionPatching(kPatchableCode2, override));
5609642e337SNico Weber #if SANITIZER_WINDOWS64
5619642e337SNico Weber   EXPECT_FALSE(TestFunctionPatching(kPatchableCode3, override));
5629642e337SNico Weber #else
5639642e337SNico Weber   EXPECT_TRUE(TestFunctionPatching(kPatchableCode3, override));
5649642e337SNico Weber #endif
5659642e337SNico Weber   EXPECT_TRUE(TestFunctionPatching(kPatchableCode4, override));
5669642e337SNico Weber   EXPECT_TRUE(TestFunctionPatching(kPatchableCode5, override));
5679642e337SNico Weber #if SANITIZER_WINDOWS64
5689642e337SNico Weber   EXPECT_TRUE(TestFunctionPatching(kLoadGlobalCode, override));
5699642e337SNico Weber #endif
5709642e337SNico Weber 
5719642e337SNico Weber   EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode1, override));
5729642e337SNico Weber   EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode2, override));
5739642e337SNico Weber   EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode3, override));
5749642e337SNico Weber   EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode4, override));
5759642e337SNico Weber   EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode5, override));
5769642e337SNico Weber   EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode6, override));
5779642e337SNico Weber }
5789642e337SNico Weber 
5799642e337SNico Weber #if !SANITIZER_WINDOWS64
TEST(Interception,PatchableFunctionWithDetour)5809642e337SNico Weber TEST(Interception, PatchableFunctionWithDetour) {
5819642e337SNico Weber   TestOverrideFunction override = OverrideFunctionWithDetour;
5829642e337SNico Weber   // Without the prefix, no function can be detoured.
5839642e337SNico Weber   EXPECT_FALSE(TestFunctionPatching(kPatchableCode1, override));
5849642e337SNico Weber   EXPECT_FALSE(TestFunctionPatching(kPatchableCode2, override));
5859642e337SNico Weber   EXPECT_FALSE(TestFunctionPatching(kPatchableCode3, override));
5869642e337SNico Weber   EXPECT_FALSE(TestFunctionPatching(kPatchableCode4, override));
5879642e337SNico Weber   EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode1, override));
5889642e337SNico Weber   EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode2, override));
5899642e337SNico Weber   EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode3, override));
5909642e337SNico Weber   EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode4, override));
5919642e337SNico Weber   EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode5, override));
5929642e337SNico Weber   EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode6, override));
5939642e337SNico Weber 
5949642e337SNico Weber   // With the prefix, all functions can be detoured.
5959642e337SNico Weber   FunctionPrefixKind prefix = FunctionPrefixDetour;
5969642e337SNico Weber   EXPECT_TRUE(TestFunctionPatching(kPatchableCode1, override, prefix));
5979642e337SNico Weber   EXPECT_TRUE(TestFunctionPatching(kPatchableCode2, override, prefix));
5989642e337SNico Weber   EXPECT_TRUE(TestFunctionPatching(kPatchableCode3, override, prefix));
5999642e337SNico Weber   EXPECT_TRUE(TestFunctionPatching(kPatchableCode4, override, prefix));
6009642e337SNico Weber   EXPECT_TRUE(TestFunctionPatching(kUnpatchableCode1, override, prefix));
6019642e337SNico Weber   EXPECT_TRUE(TestFunctionPatching(kUnpatchableCode2, override, prefix));
6029642e337SNico Weber   EXPECT_TRUE(TestFunctionPatching(kUnpatchableCode3, override, prefix));
6039642e337SNico Weber   EXPECT_TRUE(TestFunctionPatching(kUnpatchableCode4, override, prefix));
6049642e337SNico Weber   EXPECT_TRUE(TestFunctionPatching(kUnpatchableCode5, override, prefix));
6059642e337SNico Weber   EXPECT_TRUE(TestFunctionPatching(kUnpatchableCode6, override, prefix));
6069642e337SNico Weber }
6079642e337SNico Weber #endif  // !SANITIZER_WINDOWS64
6089642e337SNico Weber 
TEST(Interception,PatchableFunctionWithRedirectJump)6099642e337SNico Weber TEST(Interception, PatchableFunctionWithRedirectJump) {
6109642e337SNico Weber   TestOverrideFunction override = OverrideFunctionWithRedirectJump;
6119642e337SNico Weber   EXPECT_FALSE(TestFunctionPatching(kPatchableCode1, override));
6129642e337SNico Weber   EXPECT_FALSE(TestFunctionPatching(kPatchableCode2, override));
6139642e337SNico Weber   EXPECT_FALSE(TestFunctionPatching(kPatchableCode3, override));
6149642e337SNico Weber   EXPECT_TRUE(TestFunctionPatching(kPatchableCode4, override));
6159642e337SNico Weber   EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode1, override));
6169642e337SNico Weber   EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode2, override));
6179642e337SNico Weber   EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode3, override));
6189642e337SNico Weber   EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode4, override));
6199642e337SNico Weber   EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode5, override));
6209642e337SNico Weber   EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode6, override));
6219642e337SNico Weber }
6229642e337SNico Weber 
TEST(Interception,PatchableFunctionWithHotPatch)6239642e337SNico Weber TEST(Interception, PatchableFunctionWithHotPatch) {
6249642e337SNico Weber   TestOverrideFunction override = OverrideFunctionWithHotPatch;
6259642e337SNico Weber   FunctionPrefixKind prefix = FunctionPrefixHotPatch;
6269642e337SNico Weber 
6279642e337SNico Weber   EXPECT_TRUE(TestFunctionPatching(kPatchableCode1, override, prefix));
6289642e337SNico Weber   EXPECT_FALSE(TestFunctionPatching(kPatchableCode2, override, prefix));
6299642e337SNico Weber   EXPECT_FALSE(TestFunctionPatching(kPatchableCode3, override, prefix));
6309642e337SNico Weber   EXPECT_FALSE(TestFunctionPatching(kPatchableCode4, override, prefix));
6319642e337SNico Weber #if SANITIZER_WINDOWS64
6329642e337SNico Weber   EXPECT_TRUE(TestFunctionPatching(kPatchableCode6, override, prefix));
6339642e337SNico Weber   EXPECT_TRUE(TestFunctionPatching(kPatchableCode7, override, prefix));
6349642e337SNico Weber   EXPECT_TRUE(TestFunctionPatching(kPatchableCode8, override, prefix));
6359642e337SNico Weber #endif
6369642e337SNico Weber   EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode1, override, prefix));
6379642e337SNico Weber   EXPECT_TRUE(TestFunctionPatching(kUnpatchableCode2, override, prefix));
6389642e337SNico Weber   EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode3, override, prefix));
6399642e337SNico Weber   EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode4, override, prefix));
6409642e337SNico Weber   EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode5, override, prefix));
6419642e337SNico Weber   EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode6, override, prefix));
6429642e337SNico Weber }
6439642e337SNico Weber 
TEST(Interception,PatchableFunctionWithTrampoline)6449642e337SNico Weber TEST(Interception, PatchableFunctionWithTrampoline) {
6459642e337SNico Weber   TestOverrideFunction override = OverrideFunctionWithTrampoline;
6469642e337SNico Weber   FunctionPrefixKind prefix = FunctionPrefixPadding;
6479642e337SNico Weber 
6489642e337SNico Weber   EXPECT_TRUE(TestFunctionPatching(kPatchableCode1, override, prefix));
6499642e337SNico Weber   EXPECT_TRUE(TestFunctionPatching(kPatchableCode2, override, prefix));
6509642e337SNico Weber #if SANITIZER_WINDOWS64
6519642e337SNico Weber   EXPECT_FALSE(TestFunctionPatching(kPatchableCode3, override, prefix));
652*22ea0ceaSToshihito Kikuchi   EXPECT_TRUE(TestFunctionPatching(kPatchableCode9, override, prefix));
653*22ea0ceaSToshihito Kikuchi   EXPECT_TRUE(TestFunctionPatching(kPatchableCode10, override, prefix));
654*22ea0ceaSToshihito Kikuchi   EXPECT_TRUE(TestFunctionPatching(kPatchableCode11, override, prefix));
655*22ea0ceaSToshihito Kikuchi   EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode7, override, prefix));
656*22ea0ceaSToshihito Kikuchi   EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode8, override, prefix));
657*22ea0ceaSToshihito Kikuchi   EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode9, override, prefix));
6589642e337SNico Weber #else
6599642e337SNico Weber   EXPECT_TRUE(TestFunctionPatching(kPatchableCode3, override, prefix));
6609642e337SNico Weber #endif
6619642e337SNico Weber   EXPECT_FALSE(TestFunctionPatching(kPatchableCode4, override, prefix));
6629642e337SNico Weber 
6639642e337SNico Weber   EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode1, override, prefix));
6649642e337SNico Weber   EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode2, override, prefix));
6659642e337SNico Weber   EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode3, override, prefix));
6669642e337SNico Weber   EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode4, override, prefix));
6679642e337SNico Weber   EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode5, override, prefix));
6689642e337SNico Weber   EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode6, override, prefix));
6699642e337SNico Weber }
6709642e337SNico Weber 
TEST(Interception,PatchableFunctionPadding)6719642e337SNico Weber TEST(Interception, PatchableFunctionPadding) {
6729642e337SNico Weber   TestOverrideFunction override = OverrideFunction;
6739642e337SNico Weber   FunctionPrefixKind prefix = FunctionPrefixPadding;
6749642e337SNico Weber 
6759642e337SNico Weber   EXPECT_TRUE(TestFunctionPatching(kPatchableCode1, override, prefix));
6769642e337SNico Weber   EXPECT_TRUE(TestFunctionPatching(kPatchableCode2, override, prefix));
6779642e337SNico Weber #if SANITIZER_WINDOWS64
6789642e337SNico Weber   EXPECT_FALSE(TestFunctionPatching(kPatchableCode3, override, prefix));
6799642e337SNico Weber #else
6809642e337SNico Weber   EXPECT_TRUE(TestFunctionPatching(kPatchableCode3, override, prefix));
6819642e337SNico Weber #endif
6829642e337SNico Weber   EXPECT_TRUE(TestFunctionPatching(kPatchableCode4, override, prefix));
6839642e337SNico Weber 
6849642e337SNico Weber   EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode1, override, prefix));
6859642e337SNico Weber   EXPECT_TRUE(TestFunctionPatching(kUnpatchableCode2, override, prefix));
6869642e337SNico Weber   EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode3, override, prefix));
6879642e337SNico Weber   EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode4, override, prefix));
6889642e337SNico Weber   EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode5, override, prefix));
6899642e337SNico Weber   EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode6, override, prefix));
6909642e337SNico Weber }
6919642e337SNico Weber 
TEST(Interception,EmptyExportTable)6929642e337SNico Weber TEST(Interception, EmptyExportTable) {
6939642e337SNico Weber   // We try to get a pointer to a function from an executable that doesn't
6949642e337SNico Weber   // export any symbol (empty export table).
6959642e337SNico Weber   uptr FunPtr = InternalGetProcAddress((void *)GetModuleHandleA(0), "example");
6969642e337SNico Weber   EXPECT_EQ(0U, FunPtr);
6979642e337SNico Weber }
6989642e337SNico Weber 
6999642e337SNico Weber }  // namespace __interception
7009642e337SNico Weber 
7019642e337SNico Weber #endif  // SANITIZER_WINDOWS
7029642e337SNico Weber #endif  // #if !SANITIZER_DEBUG
703