diff options
Diffstat (limited to 'lib/interception/tests')
-rw-r--r-- | lib/interception/tests/CMakeLists.txt | 1 | ||||
-rw-r--r-- | lib/interception/tests/interception_linux_test.cc | 7 | ||||
-rw-r--r-- | lib/interception/tests/interception_win_test.cc | 39 |
3 files changed, 39 insertions, 8 deletions
diff --git a/lib/interception/tests/CMakeLists.txt b/lib/interception/tests/CMakeLists.txt index bfe41fed2fed5..5ea943f9a82a6 100644 --- a/lib/interception/tests/CMakeLists.txt +++ b/lib/interception/tests/CMakeLists.txt @@ -29,6 +29,7 @@ else() endif() if(MSVC) list(APPEND INTERCEPTION_TEST_CFLAGS_COMMON -gcodeview) + list(APPEND INTERCEPTION_TEST_LINK_FLAGS_COMMON -Wl,-largeaddressaware) endif() list(APPEND INTERCEPTION_TEST_LINK_FLAGS_COMMON -g) diff --git a/lib/interception/tests/interception_linux_test.cc b/lib/interception/tests/interception_linux_test.cc index 4a1ae785d16f4..cc09aa09df3a4 100644 --- a/lib/interception/tests/interception_linux_test.cc +++ b/lib/interception/tests/interception_linux_test.cc @@ -11,6 +11,10 @@ // Tests for interception_linux.h. // //===----------------------------------------------------------------------===// + +// Do not declare isdigit in ctype.h. +#define __NO_CTYPE + #include "interception/interception.h" #include "gtest/gtest.h" @@ -31,10 +35,9 @@ INTERCEPTOR(int, isdigit, int d) { namespace __interception { TEST(Interception, GetRealFunctionAddress) { - uptr expected_malloc_address = (uptr)(void*)&malloc; uptr malloc_address = 0; EXPECT_TRUE(GetRealFunctionAddress("malloc", &malloc_address, 0, 0)); - EXPECT_EQ(expected_malloc_address, malloc_address); + EXPECT_NE(0U, malloc_address); uptr dummy_address = 0; EXPECT_TRUE( diff --git a/lib/interception/tests/interception_win_test.cc b/lib/interception/tests/interception_win_test.cc index 611354f03d12b..684ee03035590 100644 --- a/lib/interception/tests/interception_win_test.cc +++ b/lib/interception/tests/interception_win_test.cc @@ -163,6 +163,13 @@ const u8 kPatchableCode4[] = { 0x90, 0x90, 0x90, 0x90, }; +const u8 kPatchableCode5[] = { + 0x55, // push ebp + 0x8b, 0xec, // mov ebp,esp + 0x8d, 0xa4, 0x24, 0x30, 0xfd, 0xff, 0xff, // lea esp,[esp-2D0h] + 0x54, // push esp +}; + const u8 kUnpatchableCode1[] = { 0xC3, // ret }; @@ -197,7 +204,29 @@ const u8 kUnpatchableCode6[] = { // A buffer holding the dynamically generated code under test. u8* ActiveCode; -size_t ActiveCodeLength = 4096; +const size_t ActiveCodeLength = 4096; + +int InterceptorFunction(int x); + +/// Allocate code memory more than 2GB away from Base. +u8 *AllocateCode2GBAway(u8 *Base) { + // Find a 64K aligned location after Base plus 2GB. + size_t TwoGB = 0x80000000; + size_t AllocGranularity = 0x10000; + Base = (u8 *)((((uptr)Base + TwoGB + AllocGranularity)) & ~(AllocGranularity - 1)); + + // Check if that location is free, and if not, loop over regions until we find + // one that is. + MEMORY_BASIC_INFORMATION mbi = {}; + while (sizeof(mbi) == VirtualQuery(Base, &mbi, sizeof(mbi))) { + if (mbi.State & MEM_FREE) break; + Base += mbi.RegionSize; + } + + // Allocate one RWX page at the free location. + return (u8 *)::VirtualAlloc(Base, ActiveCodeLength, MEM_COMMIT | MEM_RESERVE, + PAGE_EXECUTE_READWRITE); +} template<class T> static void LoadActiveCode( @@ -205,11 +234,8 @@ static void LoadActiveCode( uptr *entry_point, FunctionPrefixKind prefix_kind = FunctionPrefixNone) { if (ActiveCode == nullptr) { - ActiveCode = - (u8*)::VirtualAlloc(nullptr, ActiveCodeLength, - MEM_COMMIT | MEM_RESERVE, - PAGE_EXECUTE_READWRITE); - ASSERT_NE(ActiveCode, nullptr); + ActiveCode = AllocateCode2GBAway((u8*)&InterceptorFunction); + ASSERT_NE(ActiveCode, nullptr) << "failed to allocate RWX memory 2GB away"; } size_t position = 0; @@ -474,6 +500,7 @@ TEST(Interception, PatchableFunction) { EXPECT_TRUE(TestFunctionPatching(kPatchableCode3, override)); #endif EXPECT_TRUE(TestFunctionPatching(kPatchableCode4, override)); + EXPECT_TRUE(TestFunctionPatching(kPatchableCode5, override)); EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode1, override)); EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode2, override)); |