[PATCH 3/3] ntdll: Only raise EXCEPTION_INVALID_HANDLE if debugger is present.

Rémi Bernon rbernon at codeweavers.com
Mon Jun 22 16:27:49 CDT 2020


CoD: WWII writes to PEB->BeingDebugged field, so we cannot completely
trust it, but we can double check with ProcessDebugPort.

Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---
 dlls/ntdll/om.c              |  5 ++++-
 dlls/ntdll/tests/exception.c | 12 ++++++++++++
 2 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/dlls/ntdll/om.c b/dlls/ntdll/om.c
index aaed9abaa93..992d05d4769 100644
--- a/dlls/ntdll/om.c
+++ b/dlls/ntdll/om.c
@@ -364,9 +364,12 @@ static LONG WINAPI invalid_handle_exception_handler( EXCEPTION_POINTERS *eptr )
 /* Everquest 2 / Pirates of the Burning Sea hooks NtClose, so we need a wrapper */
 NTSTATUS close_handle( HANDLE handle )
 {
+    DWORD_PTR debug_port;
     NTSTATUS ret = unix_funcs->NtClose( handle );
 
-    if (ret == STATUS_INVALID_HANDLE && handle && NtCurrentTeb()->Peb->BeingDebugged)
+    if (ret == STATUS_INVALID_HANDLE && handle && NtCurrentTeb()->Peb->BeingDebugged &&
+        !FAILED(NtQueryInformationProcess( NtCurrentProcess(), ProcessDebugPort, &debug_port,
+                                           sizeof(debug_port), NULL)) && debug_port)
     {
         __TRY
         {
diff --git a/dlls/ntdll/tests/exception.c b/dlls/ntdll/tests/exception.c
index a5e6faa461a..411439f180f 100644
--- a/dlls/ntdll/tests/exception.c
+++ b/dlls/ntdll/tests/exception.c
@@ -3595,6 +3595,12 @@ START_TEST(exception)
     test_suspend_process();
     test_unload_trace();
 
+    /* Call of Duty WWII writes to BeingDebugged then closes an invalid handle,
+     * crashing the game if an exception is raised. */
+    NtCurrentTeb()->Peb->BeingDebugged = 0x98;
+    test_closehandle(0, (HANDLE)0xdeadbeef);
+    NtCurrentTeb()->Peb->BeingDebugged = 0;
+
 #elif defined(__x86_64__)
 
 #define X(f) p##f = (void*)GetProcAddress(hntdll, #f)
@@ -3638,6 +3644,12 @@ START_TEST(exception)
     else
       skip( "Dynamic unwind functions not found\n" );
 
+    /* Call of Duty WWII writes to BeingDebugged then closes an invalid handle,
+     * crashing the game if an exception is raised. */
+    NtCurrentTeb()->Peb->BeingDebugged = 0x98;
+    test_closehandle(0, (HANDLE)0xdeadbeef);
+    NtCurrentTeb()->Peb->BeingDebugged = 0;
+
 #endif
 
     VirtualFree(code_mem, 0, MEM_RELEASE);
-- 
2.27.0




More information about the wine-devel mailing list