ntdll: Only raise EXCEPTION_INVALID_HANDLE if debugger is present.

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@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Rémi Bernon 2020-06-22 23:27:49 +02:00 committed by Alexandre Julliard
parent 537bb7a8ae
commit b7ccb9d06a
2 changed files with 16 additions and 1 deletions

View File

@ -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 &&
!NtQueryInformationProcess( NtCurrentProcess(), ProcessDebugPort, &debug_port,
sizeof(debug_port), NULL) && debug_port)
{
__TRY
{

View File

@ -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);