From 863fda0b0f0d11a0e1cd191ac1b82412f9851a5d Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Fri, 23 Jul 2021 17:10:57 +0200 Subject: [PATCH] wow64: Add thunks for the debug object syscalls. Signed-off-by: Alexandre Julliard --- dlls/wow64/struct32.h | 57 +++++++++++++++++++++ dlls/wow64/sync.c | 125 +++++++++++++++++++++++++++++++++++++++++++++ dlls/wow64/syscall.h | 4 ++ dlls/wow64/wow64_private.h | 8 +++ 4 files changed, 194 insertions(+) diff --git a/dlls/wow64/struct32.h b/dlls/wow64/struct32.h index 23144e9e15a..776b1d4df35 100644 --- a/dlls/wow64/struct32.h +++ b/dlls/wow64/struct32.h @@ -37,4 +37,61 @@ typedef struct UNICODE_STRING32 ObjectTypeName; } DIRECTORY_BASIC_INFORMATION32; +typedef struct +{ + DBG_STATE NewState; + CLIENT_ID32 AppClientId; + union + { + struct + { + EXCEPTION_RECORD32 ExceptionRecord; + ULONG FirstChance; + } Exception; + struct + { + ULONG HandleToThread; + struct + { + ULONG SubSystemKey; + ULONG StartAddress; + } NewThread; + } CreateThread; + struct + { + ULONG HandleToProcess; + ULONG HandleToThread; + struct + { + ULONG SubSystemKey; + ULONG FileHandle; + ULONG BaseOfImage; + ULONG DebugInfoFileOffset; + ULONG DebugInfoSize; + struct + { + ULONG SubSystemKey; + ULONG StartAddress; + } InitialThread; + } NewProcess; + } CreateProcessInfo; + struct + { + NTSTATUS ExitStatus; + } ExitProcess, ExitThread; + struct + { + ULONG FileHandle; + ULONG BaseOfDll; + ULONG DebugInfoFileOffset; + ULONG DebugInfoSize; + ULONG NamePointer; + } LoadDll; + struct + { + ULONG BaseAddress; + } UnloadDll; + } StateInfo; +} DBGUI_WAIT_STATE_CHANGE32; + #endif /* __WOW64_STRUCT32_H */ diff --git a/dlls/wow64/sync.c b/dlls/wow64/sync.c index 55c0ed08e32..d280f1324a3 100644 --- a/dlls/wow64/sync.c +++ b/dlls/wow64/sync.c @@ -56,6 +56,27 @@ NTSTATUS WINAPI wow64_NtClearEvent( UINT *args ) /********************************************************************** + * wow64_NtCreateDebugObject + */ +NTSTATUS WINAPI wow64_NtCreateDebugObject( UINT *args ) +{ + ULONG *handle_ptr = get_ptr( &args ); + ACCESS_MASK access = get_ulong( &args ); + OBJECT_ATTRIBUTES32 *attr32 = get_ptr( &args ); + ULONG flags = get_ulong( &args ); + + struct object_attr64 attr; + HANDLE handle = 0; + NTSTATUS status; + + *handle_ptr = 0; + status = NtCreateDebugObject( &handle, access, objattr_32to64( &attr, attr32 ), flags ); + put_handle( handle_ptr, handle ); + return status; +} + + +/********************************************************************** * wow64_NtCreateDirectoryObject */ NTSTATUS WINAPI wow64_NtCreateDirectoryObject( UINT *args ) @@ -183,6 +204,21 @@ NTSTATUS WINAPI wow64_NtCreateTimer( UINT *args ) /********************************************************************** + * wow64_NtDebugContinue + */ +NTSTATUS WINAPI wow64_NtDebugContinue( UINT *args ) +{ + HANDLE handle = get_handle( &args ); + CLIENT_ID32 *id32 = get_ptr( &args ); + NTSTATUS status = get_ulong( &args ); + + CLIENT_ID id; + + return NtDebugContinue( handle, client_id_32to64( &id, id32 ), status ); +} + + +/********************************************************************** * wow64_NtOpenDirectoryObject */ NTSTATUS WINAPI wow64_NtOpenDirectoryObject( UINT *args ) @@ -475,6 +511,21 @@ NTSTATUS WINAPI wow64_NtSetEvent( UINT *args ) /********************************************************************** + * wow64_NtSetInformationDebugObject + */ +NTSTATUS WINAPI wow64_NtSetInformationDebugObject( UINT *args ) +{ + HANDLE handle = get_handle( &args ); + DEBUGOBJECTINFOCLASS class = get_ulong( &args ); + void *ptr = get_ptr( &args ); + ULONG len = get_ulong( &args ); + ULONG *retlen = get_ptr( &args ); + + return NtSetInformationDebugObject( handle, class, ptr, len, retlen ); +} + + +/********************************************************************** * wow64_NtSetTimer */ NTSTATUS WINAPI wow64_NtSetTimer( UINT *args ) @@ -493,6 +544,80 @@ NTSTATUS WINAPI wow64_NtSetTimer( UINT *args ) /********************************************************************** + * wow64_NtWaitForDebugEvent + */ +NTSTATUS WINAPI wow64_NtWaitForDebugEvent( UINT *args ) +{ + HANDLE handle = get_handle( &args ); + BOOLEAN alertable = get_ulong( &args ); + LARGE_INTEGER *timeout = get_ptr( &args ); + DBGUI_WAIT_STATE_CHANGE32 *state32 = get_ptr( &args ); + + ULONG i; + DBGUI_WAIT_STATE_CHANGE state; + NTSTATUS status = NtWaitForDebugEvent( handle, alertable, timeout, &state ); + + if (!status) + { + state32->NewState = state.NewState; + state32->AppClientId.UniqueProcess = HandleToULong( state.AppClientId.UniqueProcess ); + state32->AppClientId.UniqueThread = HandleToULong( state.AppClientId.UniqueThread ); + switch (state.NewState) + { +#define COPY_ULONG(field) state32->StateInfo.field = state.StateInfo.field +#define COPY_PTR(field) state32->StateInfo.field = PtrToUlong( state.StateInfo.field ) + case DbgCreateThreadStateChange: + COPY_PTR( CreateThread.HandleToThread ); + COPY_PTR( CreateThread.NewThread.StartAddress ); + COPY_ULONG( CreateThread.NewThread.SubSystemKey ); + break; + case DbgCreateProcessStateChange: + COPY_PTR( CreateProcessInfo.HandleToProcess ); + COPY_PTR( CreateProcessInfo.HandleToThread ); + COPY_PTR( CreateProcessInfo.NewProcess.FileHandle ); + COPY_PTR( CreateProcessInfo.NewProcess.BaseOfImage ); + COPY_PTR( CreateProcessInfo.NewProcess.InitialThread.StartAddress ); + COPY_ULONG( CreateProcessInfo.NewProcess.InitialThread.SubSystemKey ); + COPY_ULONG( CreateProcessInfo.NewProcess.DebugInfoFileOffset ); + COPY_ULONG( CreateProcessInfo.NewProcess.DebugInfoSize ); + break; + case DbgExitThreadStateChange: + case DbgExitProcessStateChange: + COPY_ULONG( ExitThread.ExitStatus ); + break; + case DbgExceptionStateChange: + case DbgBreakpointStateChange: + case DbgSingleStepStateChange: + COPY_ULONG( Exception.FirstChance ); + COPY_ULONG( Exception.ExceptionRecord.ExceptionCode ); + COPY_ULONG( Exception.ExceptionRecord.ExceptionFlags ); + COPY_ULONG( Exception.ExceptionRecord.NumberParameters ); + COPY_PTR( Exception.ExceptionRecord.ExceptionRecord ); + COPY_PTR( Exception.ExceptionRecord.ExceptionAddress ); + for (i = 0; i < state.StateInfo.Exception.ExceptionRecord.NumberParameters; i++) + COPY_ULONG( Exception.ExceptionRecord.ExceptionInformation[i] ); + break; + case DbgLoadDllStateChange: + COPY_PTR( LoadDll.FileHandle ); + COPY_PTR( LoadDll.BaseOfDll ); + COPY_ULONG( LoadDll.DebugInfoFileOffset ); + COPY_ULONG( LoadDll.DebugInfoSize ); + COPY_PTR( LoadDll.NamePointer ); + break; + case DbgUnloadDllStateChange: + COPY_PTR( UnloadDll.BaseAddress ); + break; + default: + break; + } +#undef COPY_ULONG +#undef COPY_PTR + } + return status; +} + + +/********************************************************************** * wow64_NtWaitForKeyedEvent */ NTSTATUS WINAPI wow64_NtWaitForKeyedEvent( UINT *args ) diff --git a/dlls/wow64/syscall.h b/dlls/wow64/syscall.h index b64cabd15b5..a56e775bda3 100644 --- a/dlls/wow64/syscall.h +++ b/dlls/wow64/syscall.h @@ -28,12 +28,14 @@ SYSCALL_ENTRY( NtCancelTimer ) \ SYSCALL_ENTRY( NtClearEvent ) \ SYSCALL_ENTRY( NtClose ) \ + SYSCALL_ENTRY( NtCreateDebugObject ) \ SYSCALL_ENTRY( NtCreateDirectoryObject ) \ SYSCALL_ENTRY( NtCreateEvent ) \ SYSCALL_ENTRY( NtCreateKeyedEvent ) \ SYSCALL_ENTRY( NtCreateMutant ) \ SYSCALL_ENTRY( NtCreateSemaphore ) \ SYSCALL_ENTRY( NtCreateTimer ) \ + SYSCALL_ENTRY( NtDebugContinue ) \ SYSCALL_ENTRY( NtDeleteAtom ) \ SYSCALL_ENTRY( NtFindAtom ) \ SYSCALL_ENTRY( NtGetCurrentProcessorNumber ) \ @@ -60,7 +62,9 @@ SYSCALL_ENTRY( NtSetDefaultLocale ) \ SYSCALL_ENTRY( NtSetDefaultUILanguage ) \ SYSCALL_ENTRY( NtSetEvent ) \ + SYSCALL_ENTRY( NtSetInformationDebugObject ) \ SYSCALL_ENTRY( NtSetTimer ) \ + SYSCALL_ENTRY( NtWaitForDebugEvent ) \ SYSCALL_ENTRY( NtWaitForKeyedEvent ) #endif /* __WOW64_SYSCALL_H */ diff --git a/dlls/wow64/wow64_private.h b/dlls/wow64/wow64_private.h index f555f8db7bb..9e3fd914045 100644 --- a/dlls/wow64/wow64_private.h +++ b/dlls/wow64/wow64_private.h @@ -83,6 +83,14 @@ static inline UNICODE_STRING *unicode_str_32to64( UNICODE_STRING *str, const UNI return str; } +static inline CLIENT_ID *client_id_32to64( CLIENT_ID *id, const CLIENT_ID32 *id32 ) +{ + if (!id32) return NULL; + id->UniqueProcess = LongToHandle( id32->UniqueProcess ); + id->UniqueThread = LongToHandle( id32->UniqueThread ); + return id; +} + static inline SECURITY_DESCRIPTOR *secdesc_32to64( SECURITY_DESCRIPTOR *out, const SECURITY_DESCRIPTOR *in ) { /* relative descr has the same layout for 32 and 64 */ -- 2.11.4.GIT