From 2d487f2dd6b3c4aa901b381b28b7539d39b19ffe Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Fri, 27 Apr 2012 12:07:15 +0000 Subject: [PATCH] * path.cc (find_fast_cwd_pointer): Fix for W8 CP 32 bit. --- winsup/cygwin/ChangeLog | 4 +++ winsup/cygwin/path.cc | 75 +++++++++++++++++++++++++++++------------ 2 files changed, 58 insertions(+), 21 deletions(-) diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 1300321f5..c8186e4e7 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,7 @@ +2012-04-27 Corinna Vinschen + + * path.cc (find_fast_cwd_pointer): Fix for W8 CP 32 bit. + 2012-04-25 Thomas Wolff * fhandler.h (class dev_console): Add member ext_mouse_mode5. diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc index 3524c0cc0..59e6de384 100644 --- a/winsup/cygwin/path.cc +++ b/winsup/cygwin/path.cc @@ -3699,31 +3699,64 @@ find_fast_cwd_pointer () /* ...which should be followed by "mov edi, crit-sect-addr" then "push edi", or by just a single "push crit-sect-addr". */ const uint8_t *movedi = pushedi + 1; - if (movedi[0] == 0xbf && movedi[5] == 0x57) - rcall = movedi + 6; - else if (movedi[0] == 0x68) - rcall = movedi + 5; + const uint8_t *mov_pfast_cwd; + if (movedi[0] == 0x8b && movedi[1] == 0xff) /* mov edi,edi -> W8 */ + { + /* Windows 8 CP 32 bit (after a Windows Update?) does not call + RtlEnterCriticalSection. For some reason the function manipulates + the FastPebLock manually, kind of like RtlEnterCriticalSection has + been converted to an inline function. + + Next we search for a `mov eax, some address'. This address points + to the LockCount member of the FastPebLock structure, so the address + is equal to FastPebLock + 4. */ + const uint8_t *moveax = (const uint8_t *) memchr (movedi, 0xb8, 16); + if (!moveax) + return NULL; + offset = (ptrdiff_t) peek32 (moveax + 1) - 4; + /* Compare the address with the known PEB lock as stored in the PEB. */ + if ((PRTL_CRITICAL_SECTION) offset != NtCurrentTeb ()->Peb->FastPebLock) + return NULL; + /* Now search for the mov instruction fetching the address of the global + PFAST_CWD *. */ + mov_pfast_cwd = moveax; + do + { + mov_pfast_cwd = (const uint8_t *) memchr (++mov_pfast_cwd, 0x8b, 48); + } + while (mov_pfast_cwd && mov_pfast_cwd[1] != 0x1d + && (mov_pfast_cwd - moveax) < 48); + if (!mov_pfast_cwd || mov_pfast_cwd[1] != 0x1d) + return NULL; + } else - return NULL; - /* Compare the address used for the critical section with the known - PEB lock as stored in the PEB. */ - if ((PRTL_CRITICAL_SECTION) peek32 (movedi + 1) - != NtCurrentTeb ()->Peb->FastPebLock) - return NULL; - /* To check we are seeing the right code, we check our expectation that - the next instruction is a relative call into RtlEnterCriticalSection. */ - if (rcall[0] != 0xe8) - return NULL; - /* Check that this is a relative call to RtlEnterCriticalSection. */ - offset = (ptrdiff_t) peek32 (rcall + 1); - if (rcall + 5 + offset != ent_crit) - return NULL; + { + if (movedi[0] == 0xbf && movedi[5] == 0x57) + rcall = movedi + 6; + else if (movedi[0] == 0x68) + rcall = movedi + 5; + else + return NULL; + /* Compare the address used for the critical section with the known + PEB lock as stored in the PEB. */ + if ((PRTL_CRITICAL_SECTION) peek32 (movedi + 1) + != NtCurrentTeb ()->Peb->FastPebLock) + return NULL; + /* To check we are seeing the right code, we check our expectation that + the next instruction is a relative call into RtlEnterCriticalSection. */ + if (rcall[0] != 0xe8) + return NULL; + /* Check that this is a relative call to RtlEnterCriticalSection. */ + offset = (ptrdiff_t) peek32 (rcall + 1); + if (rcall + 5 + offset != ent_crit) + return NULL; + mov_pfast_cwd = rcall + 5; + } /* After locking the critical section, the code should read the global PFAST_CWD * pointer that is guarded by that critical section. */ - const uint8_t *movesi = rcall + 5; - if (movesi[0] != 0x8b) + if (mov_pfast_cwd[0] != 0x8b) return NULL; - return (fcwd_access_t **) peek32 (movesi + 2); + return (fcwd_access_t **) peek32 (mov_pfast_cwd + 2); } static fcwd_access_t **