|
| 1 | +From b80da35c1f6a619acf53be8db4a6691937dbefef Mon Sep 17 00:00:00 2001 |
| 2 | +From: Johannes Schindelin < [email protected]> |
| 3 | +Date: Mon, 22 May 2023 13:36:27 +0200 |
| 4 | +Subject: [PATCH 54/N] Cygwin: Adjust CWD magic to accommodate for the latest |
| 5 | + Windows previews |
| 6 | + |
| 7 | +Reportedly a very recent internal build of Windows 11 once again changed |
| 8 | +the current working directory logic a bit, and Cygwin's "magic" (or: |
| 9 | +"technologically sufficiently advanced") code needs to be adjusted |
| 10 | +accordingly. |
| 11 | + |
| 12 | +In particular, the following assembly code can be seen: |
| 13 | + |
| 14 | +ntdll!RtlpReferenceCurrentDirectory |
| 15 | + |
| 16 | + 598 00000001`800c6925 488d0db4cd0f00 lea rcx,[ntdll!FastPebLock (00000001`801c36e0)] |
| 17 | + 583 00000001`800c692c 4c897810 mov qword ptr [rax+10h],r15 |
| 18 | + 588 00000001`800c6930 0f1140c8 movups xmmword ptr [rax-38h],xmm0 |
| 19 | + 598 00000001`800c6934 e82774f4ff call ntdll!RtlEnterCriticalSection |
| 20 | + |
| 21 | +The change necessarily looks a bit different than 4840a56325 (Cygwin: |
| 22 | +Adjust CWD magic to accommodate for the latest Windows previews, |
| 23 | +2023-05-22): The needle `\x48\x8d\x0d` is already present, as the first |
| 24 | +version of the hack after Windows 8.1 was released. In that code, |
| 25 | +though, the `call` to `RtlEnterCriticalSection` followed the `lea` |
| 26 | +instruction immediately, but now there are two more instructions |
| 27 | +separating them. |
| 28 | + |
| 29 | +Note: In the long run, we may very well want to follow the insightful |
| 30 | +suggestion by a helpful Windows kernel engineer who pointed out that it |
| 31 | +may be less fragile to implement kind of a disassembler that has a |
| 32 | +better chance to adapt to the ever-changing code of |
| 33 | +`ntdll!RtlpReferenceCurrentDirectory` by skipping uninteresting |
| 34 | +instructions such as `mov %rsp,%rax`, `mov %rbx,0x20(%rax)`, `push %rsi` |
| 35 | +`sub $0x70,%rsp`, etc, and focuses on finding the `lea`, `call |
| 36 | +ntdll!RtlEnterCriticalSection` and `mov ..., rbx` instructions, much |
| 37 | +like it was prototyped out for ARM64 at |
| 38 | +https://gist.github.com/jeremyd2019/aa167df0a0ae422fa6ebaea5b60c80c9 |
| 39 | + |
| 40 | +Signed-off-by: Johannes Schindelin < [email protected]> |
| 41 | +--- |
| 42 | + winsup/cygwin/path.cc | 12 ++++++++++++ |
| 43 | + 1 file changed, 12 insertions(+) |
| 44 | + |
| 45 | +diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc |
| 46 | +index 38549ea..e78d84a 100644 |
| 47 | +--- a/winsup/cygwin/path.cc |
| 48 | ++++ b/winsup/cygwin/path.cc |
| 49 | +@@ -4794,6 +4794,18 @@ find_fast_cwd_pointer () |
| 50 | + %rcx for the subsequent RtlEnterCriticalSection call. */ |
| 51 | + lock = (const uint8_t *) memmem ((const char *) use_cwd, 80, |
| 52 | + "\x48\x8d\x0d", 3); |
| 53 | ++ if (lock) |
| 54 | ++ { |
| 55 | ++ /* A recent Windows 11 Preview calls `lea rel(rip),%rcx' then |
| 56 | ++ a `mov` and a `movups` instruction, and only then |
| 57 | ++ `callq RtlEnterCriticalSection'. |
| 58 | ++ */ |
| 59 | ++ if (memmem (lock + 7, 8, "\x4c\x89\x78\x10\x0f\x11\x40\xc8", 8)) |
| 60 | ++ { |
| 61 | ++ call_rtl_offset = 15; |
| 62 | ++ } |
| 63 | ++ } |
| 64 | ++ |
| 65 | + if (!lock) |
| 66 | + { |
| 67 | + /* Windows 8.1 Preview calls `lea rel(rip),%r12' then some unrelated |
0 commit comments