diff options
author | Reid Kleckner <rnk@google.com> | 2017-06-16 20:44:00 +0000 |
---|---|---|
committer | Reid Kleckner <rnk@google.com> | 2017-06-16 20:44:00 +0000 |
commit | b0ee5a9393c30d2db2c6527492dfce94cefabc91 (patch) | |
tree | 089f28da5291ab78918810c22446af262d81f653 | |
parent | f91b4c62913375ae7f6c0a16e7edd9f0f2b2a443 (diff) |
[WinASan] Fix hotpatching new Win 10 build 1703 x64 strnlen prologue
The first instruction of the new ucrtbase!strnlen implementation loads a
global, presumably to dispatch between SSE and non-SSE optimized strnlen
implementations.
Fixes PR32895 and probably
https://github.com/google/sanitizers/issues/818
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@305581 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/interception/interception_win.cc | 7 | ||||
-rw-r--r-- | lib/interception/tests/interception_win_test.cc | 11 |
2 files changed, 17 insertions, 1 deletions
diff --git a/lib/interception/interception_win.cc b/lib/interception/interception_win.cc index e4f3d358f..b2902d57f 100644 --- a/lib/interception/interception_win.cc +++ b/lib/interception/interception_win.cc @@ -477,7 +477,7 @@ static size_t GetInstructionSize(uptr address, size_t* rel_offset = nullptr) { switch (*(u8*)address) { case 0xA1: // A1 XX XX XX XX XX XX XX XX : // movabs eax, dword ptr ds:[XXXXXXXX] - return 8; + return 9; } switch (*(u16*)address) { @@ -495,6 +495,11 @@ static size_t GetInstructionSize(uptr address, size_t* rel_offset = nullptr) { case 0x5741: // push r15 case 0x9066: // Two-byte NOP return 2; + + case 0x058B: // 8B 05 XX XX XX XX : mov eax, dword ptr [XX XX XX XX] + if (rel_offset) + *rel_offset = 2; + return 6; } switch (0x00FFFFFF & *(u32*)address) { diff --git a/lib/interception/tests/interception_win_test.cc b/lib/interception/tests/interception_win_test.cc index a705768d6..37ef994f8 100644 --- a/lib/interception/tests/interception_win_test.cc +++ b/lib/interception/tests/interception_win_test.cc @@ -170,6 +170,13 @@ const u8 kPatchableCode5[] = { 0x54, // push esp }; +#if SANITIZER_WINDOWS64 +u8 kLoadGlobalCode[] = { + 0x8B, 0x05, 0x00, 0x00, 0x00, 0x00, // mov eax [rip + global] + 0xC3, // ret +}; +#endif + const u8 kUnpatchableCode1[] = { 0xC3, // ret }; @@ -502,6 +509,10 @@ TEST(Interception, PatchableFunction) { EXPECT_TRUE(TestFunctionPatching(kPatchableCode4, override)); EXPECT_TRUE(TestFunctionPatching(kPatchableCode5, override)); +#if SANITIZER_WINDOWS64 + EXPECT_TRUE(TestFunctionPatching(kLoadGlobalCode, override)); +#endif + EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode1, override)); EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode2, override)); EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode3, override)); |