summaryrefslogtreecommitdiff
path: root/lib/interception
diff options
context:
space:
mode:
authorReid Kleckner <rnk@google.com>2017-08-08 21:18:36 +0000
committerReid Kleckner <rnk@google.com>2017-08-08 21:18:36 +0000
commitdc85b2098319fb97cbedca276199188d211b6b45 (patch)
treeaa3fea67319d6d006c3d7034c5d671e5f26721aa /lib/interception
parent43c12c39b55ee6dfabb909526e3626c694958744 (diff)
[winasan] Fix hotpatching ntdll!strcpy for Win10 creators edition
The 9 byte nop is a suffix of the 10 byte nop, and we need at most 6 bytes. ntdll's version of strcpy is written in assembly and is very clever. strcat tail calls strcpy but with a slightly different arrangement of argument registers at an alternate entry point. It looks like this: ntdll!strcpy: 00007ffd`64e8a7a0 4c8bd9 mov r11,rcx ntdll!__entry_from_strcat_in_strcpy: 00007ffd`64e8a7a3 482bca sub rcx,rdx 00007ffd`64e8a7a6 f6c207 test dl,7 If we overwrite more than two bytes in our interceptor, that label will no longer be a valid instruction boundary. By recognizing the 9 byte nop, we use the two byte backwards branch to start our trampoline, avoiding this issue. Fixes https://github.com/google/sanitizers/issues/829 Patch by David Major git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@310419 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/interception')
-rw-r--r--lib/interception/interception_win.cc9
1 files changed, 4 insertions, 5 deletions
diff --git a/lib/interception/interception_win.cc b/lib/interception/interception_win.cc
index b2902d57f..3e593c98f 100644
--- a/lib/interception/interception_win.cc
+++ b/lib/interception/interception_win.cc
@@ -223,9 +223,8 @@ static bool IsMemoryPadding(uptr address, uptr size) {
return true;
}
-static const u8 kHintNop10Bytes[] = {
- 0x66, 0x66, 0x0F, 0x1F, 0x84,
- 0x00, 0x00, 0x00, 0x00, 0x00
+static const u8 kHintNop9Bytes[] = {
+ 0x66, 0x0F, 0x1F, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00
};
template<class T>
@@ -240,8 +239,8 @@ static bool FunctionHasPrefix(uptr address, const T &pattern) {
static bool FunctionHasPadding(uptr address, uptr size) {
if (IsMemoryPadding(address - size, size))
return true;
- if (size <= sizeof(kHintNop10Bytes) &&
- FunctionHasPrefix(address, kHintNop10Bytes))
+ if (size <= sizeof(kHintNop9Bytes) &&
+ FunctionHasPrefix(address, kHintNop9Bytes))
return true;
return false;
}