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