Wine-bug: https://bugs.winehq.org/show_bug.cgi?id=49903 Signed-off-by: Myah Caron qsniyg@protonmail.com --- As noted in the bug, some programs hold a breakpoint on memory reads to the TEB, and they get triggered by GetCurrentProcessId. Since this is a syscall, this wouldn't occur under Windows.
dlls/ntdll/unix/thread.c | 4 +++- server/protocol.def | 1 + server/thread.c | 1 + 3 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/dlls/ntdll/unix/thread.c b/dlls/ntdll/unix/thread.c index ded4b33eb0..9f318eaa4c 100644 --- a/dlls/ntdll/unix/thread.c +++ b/dlls/ntdll/unix/thread.c @@ -144,6 +144,7 @@ NTSTATUS WINAPI NtCreateThreadEx( HANDLE *handle, ACCESS_MASK access, OBJECT_ATT data_size_t len; struct object_attributes *objattr; struct ntdll_thread_data *thread_data; + DWORD pid = 0; DWORD tid = 0; int request_pipe[2]; SIZE_T extra_stack = PTHREAD_STACK_MIN; @@ -200,6 +201,7 @@ NTSTATUS WINAPI NtCreateThreadEx( HANDLE *handle, ACCESS_MASK access, OBJECT_ATT if (!(status = wine_server_call( req ))) { *handle = wine_server_ptr_handle( reply->handle ); + pid = reply->pid; tid = reply->tid; } close( request_pipe[0] ); @@ -223,7 +225,7 @@ NTSTATUS WINAPI NtCreateThreadEx( HANDLE *handle, ACCESS_MASK access, OBJECT_ATT goto done; }
- client_id.UniqueProcess = ULongToHandle( GetCurrentProcessId() ); + client_id.UniqueProcess = ULongToHandle( pid ); client_id.UniqueThread = ULongToHandle( tid ); teb->ClientId = client_id;
diff --git a/server/protocol.def b/server/protocol.def index f538c6dcf5..fe6a44bcda 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -832,6 +832,7 @@ struct rawinput_device int request_fd; /* fd for request pipe */ VARARG(objattr,object_attributes); /* object attributes */ @REPLY + process_id_t pid; /* process id */ thread_id_t tid; /* thread id */ obj_handle_t handle; /* thread handle (in the current process) */ @END diff --git a/server/thread.c b/server/thread.c index eb13807973..efd6a00bc4 100644 --- a/server/thread.c +++ b/server/thread.c @@ -1373,6 +1373,7 @@ DECL_HANDLER(new_thread) { thread->system_regs = current->system_regs; if (req->suspend) thread->suspend++; + reply->pid = get_process_id( process ); reply->tid = get_thread_id( thread ); if ((reply->handle = alloc_handle_no_access_check( current->process, thread, req->access, objattr->attributes ))) -- 2.28.0
I am not sure if this is acceptable either way, but wouldn't it be less of an application specific hack if to try to handle hardware breakpoints for the Unix part in a universal way in trap_handler()? As the DRM may apparently want to breakpoint any other TEB or PEB location the same way and ntdll.so is unlikely to avoid touching PEB completely.
On 9/28/20 21:59, Myah Caron wrote:
Wine-bug: https://bugs.winehq.org/show_bug.cgi?id=49903 Signed-off-by: Myah Caron qsniyg@protonmail.com
As noted in the bug, some programs hold a breakpoint on memory reads to the TEB, and they get triggered by GetCurrentProcessId. Since this is a syscall, this wouldn't occur under Windows.
dlls/ntdll/unix/thread.c | 4 +++- server/protocol.def | 1 + server/thread.c | 1 + 3 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/dlls/ntdll/unix/thread.c b/dlls/ntdll/unix/thread.c index ded4b33eb0..9f318eaa4c 100644 --- a/dlls/ntdll/unix/thread.c +++ b/dlls/ntdll/unix/thread.c @@ -144,6 +144,7 @@ NTSTATUS WINAPI NtCreateThreadEx( HANDLE *handle, ACCESS_MASK access, OBJECT_ATT data_size_t len; struct object_attributes *objattr; struct ntdll_thread_data *thread_data;
- DWORD pid = 0; DWORD tid = 0; int request_pipe[2]; SIZE_T extra_stack = PTHREAD_STACK_MIN;
@@ -200,6 +201,7 @@ NTSTATUS WINAPI NtCreateThreadEx( HANDLE *handle, ACCESS_MASK access, OBJECT_ATT if (!(status = wine_server_call( req ))) { *handle = wine_server_ptr_handle( reply->handle );
pid = reply->pid; tid = reply->tid; } close( request_pipe[0] );
@@ -223,7 +225,7 @@ NTSTATUS WINAPI NtCreateThreadEx( HANDLE *handle, ACCESS_MASK access, OBJECT_ATT goto done; }
- client_id.UniqueProcess = ULongToHandle( GetCurrentProcessId() );
- client_id.UniqueProcess = ULongToHandle( pid ); client_id.UniqueThread = ULongToHandle( tid ); teb->ClientId = client_id;
diff --git a/server/protocol.def b/server/protocol.def index f538c6dcf5..fe6a44bcda 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -832,6 +832,7 @@ struct rawinput_device int request_fd; /* fd for request pipe */ VARARG(objattr,object_attributes); /* object attributes */ @REPLY
- process_id_t pid; /* process id */ thread_id_t tid; /* thread id */ obj_handle_t handle; /* thread handle (in the current process) */ @END
diff --git a/server/thread.c b/server/thread.c index eb13807973..efd6a00bc4 100644 --- a/server/thread.c +++ b/server/thread.c @@ -1373,6 +1373,7 @@ DECL_HANDLER(new_thread) { thread->system_regs = current->system_regs; if (req->suspend) thread->suspend++;
reply->pid = get_process_id( process ); reply->tid = get_thread_id( thread ); if ((reply->handle = alloc_handle_no_access_check( current->process, thread, req->access, objattr->attributes )))
-- 2.28.0
Thanks for the reply! I'll take a closer look into trap_handler.
The DRM is wine-aware, but for an older wine version (before ntdll's move to PE). It appears to specifically create hooks around the creation of a thread, likely hooking NtCreateThreadEx itself (according to correspondence with the developers).
‐‐‐‐‐‐‐ Original Message ‐‐‐‐‐‐‐ On Tuesday, September 29, 2020 5:58 AM, Paul Gofman pgofman@codeweavers.com wrote:
I am not sure if this is acceptable either way, but wouldn't it be less of an application specific hack if to try to handle hardware breakpoints for the Unix part in a universal way in trap_handler()? As the DRM may apparently want to breakpoint any other TEB or PEB location the same way and ntdll.so is unlikely to avoid touching PEB completely.