[compiler-rt] r310419 - [winasan] Fix hotpatching ntdll!strcpy for Win10 creators edition

Reid Kleckner via llvm-commits llvm-commits at lists.llvm.org
Tue Aug 8 14:18:36 PDT 2017


Author: rnk
Date: Tue Aug  8 14:18:36 2017
New Revision: 310419

URL: http://llvm.org/viewvc/llvm-project?rev=310419&view=rev
Log:
[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

Modified:
    compiler-rt/trunk/lib/interception/interception_win.cc

Modified: compiler-rt/trunk/lib/interception/interception_win.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/interception/interception_win.cc?rev=310419&r1=310418&r2=310419&view=diff
==============================================================================
--- compiler-rt/trunk/lib/interception/interception_win.cc (original)
+++ compiler-rt/trunk/lib/interception/interception_win.cc Tue Aug  8 14:18:36 2017
@@ -223,9 +223,8 @@ static bool IsMemoryPadding(uptr address
   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 addre
 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;
 }




More information about the llvm-commits mailing list