From 5864bc88de0e0a3b1094c2bb0c16ba9a5d39ce65 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Thu, 13 May 2021 15:58:33 +0200 Subject: [PATCH] ntdll: Always send the native PEB pointer to the server. Signed-off-by: Alexandre Julliard --- dlls/ntdll/tests/info.c | 31 +++++++++++++++++++++++++++++-- dlls/ntdll/unix/process.c | 7 +++++++ dlls/ntdll/unix/server.c | 2 +- dlls/ntdll/unix/virtual.c | 8 ++++---- server/process.c | 5 +++++ 5 files changed, 46 insertions(+), 7 deletions(-) diff --git a/dlls/ntdll/tests/info.c b/dlls/ntdll/tests/info.c index 6f5ee5d2079..213ff3cde36 100644 --- a/dlls/ntdll/tests/info.c +++ b/dlls/ntdll/tests/info.c @@ -3133,6 +3133,9 @@ static void test_wow64(void) void *redir; SIZE_T res; TEB teb; + PEB peb; + TEB32 teb32; + PEB32 peb32; Wow64DisableWow64FsRedirection( &redir ); @@ -3161,14 +3164,39 @@ static void test_wow64(void) ok( (char *)teb.Tib.ExceptionList == (char *)info.TebBaseAddress + 0x2000, "wrong Tib.ExceptionList %p / %p\n", (char *)teb.Tib.ExceptionList, (char *)info.TebBaseAddress + 0x2000 ); + if (!ReadProcessMemory( pi.hProcess, teb.Tib.ExceptionList, &teb32, sizeof(teb32), &res )) res = 0; + ok( res == sizeof(teb32), "wrong len %lx\n", res ); + ok( (char *)ULongToPtr(teb32.Peb) == (char *)teb.Peb + 0x1000 || + broken( ULongToPtr(teb32.Peb) != teb.Peb ), /* vista */ + "wrong peb %p / %p\n", ULongToPtr(teb32.Peb), teb.Peb ); } status = pNtQueryInformationProcess( pi.hProcess, ProcessBasicInformation, &proc_info, sizeof(proc_info), NULL ); ok( !status, "ProcessBasicInformation failed %x\n", status ); - todo_wine_if( sizeof(void *) > sizeof(int) ) ok( proc_info.PebBaseAddress == teb.Peb, "wrong peb %p / %p\n", proc_info.PebBaseAddress, teb.Peb ); + if (!ReadProcessMemory( pi.hProcess, proc_info.PebBaseAddress, &peb, sizeof(peb), &res )) res = 0; + ok( res == sizeof(peb), "wrong len %lx\n", res ); + ok( !peb.BeingDebugged, "BeingDebugged is %u\n", peb.BeingDebugged ); + if (!is_wow64) + { + if (!ReadProcessMemory( pi.hProcess, ULongToPtr(teb32.Peb), &peb32, sizeof(peb32), &res )) res = 0; + ok( res == sizeof(peb32), "wrong len %lx\n", res ); + ok( !peb32.BeingDebugged, "BeingDebugged is %u\n", peb32.BeingDebugged ); + } + + ok( DebugActiveProcess( pi.dwProcessId ), "debugging failed\n" ); + if (!ReadProcessMemory( pi.hProcess, proc_info.PebBaseAddress, &peb, sizeof(peb), &res )) res = 0; + ok( res == sizeof(peb), "wrong len %lx\n", res ); + ok( peb.BeingDebugged == 1, "BeingDebugged is %u\n", peb.BeingDebugged ); + if (!is_wow64) + { + if (!ReadProcessMemory( pi.hProcess, ULongToPtr(teb32.Peb), &peb32, sizeof(peb32), &res )) res = 0; + ok( res == sizeof(peb32), "wrong len %lx\n", res ); + ok( peb32.BeingDebugged == 1, "BeingDebugged is %u\n", peb32.BeingDebugged ); + } + TerminateProcess( pi.hProcess, 0 ); CloseHandle( pi.hProcess ); CloseHandle( pi.hThread ); @@ -3196,7 +3224,6 @@ static void test_wow64(void) &proc_info, sizeof(proc_info), NULL ); ok( !status, "ProcessBasicInformation failed %x\n", status ); if (is_wow64) - todo_wine ok( !proc_info.PebBaseAddress || broken( (char *)proc_info.PebBaseAddress >= (char *)0x7f000000 ), /* vista */ "wrong peb %p\n", proc_info.PebBaseAddress ); diff --git a/dlls/ntdll/unix/process.c b/dlls/ntdll/unix/process.c index 79a4bbce7a8..74e16c36fd6 100644 --- a/dlls/ntdll/unix/process.c +++ b/dlls/ntdll/unix/process.c @@ -999,6 +999,13 @@ NTSTATUS WINAPI NtQueryInformationProcess( HANDLE handle, PROCESSINFOCLASS class pbi.BasePriority = reply->priority; pbi.UniqueProcessId = reply->pid; pbi.InheritedFromUniqueProcessId = reply->ppid; + if (is_wow64) + { + if (reply->machine != native_machine) + pbi.PebBaseAddress = (PEB *)((char *)pbi.PebBaseAddress + 0x1000); + else + pbi.PebBaseAddress = NULL; + } } } SERVER_END_REQ; diff --git a/dlls/ntdll/unix/server.c b/dlls/ntdll/unix/server.c index 31465c5e4dc..9f10bb135bd 100644 --- a/dlls/ntdll/unix/server.c +++ b/dlls/ntdll/unix/server.c @@ -1638,7 +1638,7 @@ void server_init_process_done(void) SERVER_START_REQ( init_process_done ) { req->teb = wine_server_client_ptr( teb ); - req->peb = wine_server_client_ptr( NtCurrentTeb()->Peb ); + req->peb = NtCurrentTeb64() ? NtCurrentTeb64()->Peb : wine_server_client_ptr( peb ); #ifdef __i386__ req->ldt_copy = wine_server_client_ptr( &__wine_ldt_copy ); #endif diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c index 84a649398bc..bcecc21989a 100644 --- a/dlls/ntdll/unix/virtual.c +++ b/dlls/ntdll/unix/virtual.c @@ -2813,8 +2813,8 @@ NTSTATUS virtual_create_builtin_view( void *module, const UNICODE_STRING *nt_nam /* set some initial values in the new PEB */ static PEB *init_peb( void *ptr ) { - PEB32 *peb32 = ptr; - PEB64 *peb64 = (PEB64 *)((char *)ptr + page_size); + PEB64 *peb64 = ptr; + PEB32 *peb32 = (PEB32 *)((char *)ptr + page_size); peb32->OSMajorVersion = peb64->OSMajorVersion = 6; peb32->OSMinorVersion = peb64->OSMinorVersion = 1; @@ -2839,7 +2839,7 @@ static TEB *init_teb( void *ptr, PEB *peb, BOOL is_wow ) #ifdef _WIN64 teb = (TEB *)teb64; - teb32->Peb = PtrToUlong( (char *)peb - page_size ); + teb32->Peb = PtrToUlong( (char *)peb + page_size ); teb32->Tib.Self = PtrToUlong( teb32 ); teb32->Tib.ExceptionList = ~0u; teb32->ActivationContextStackPointer = PtrToUlong( &teb32->ActivationContextStack ); @@ -2853,7 +2853,7 @@ static TEB *init_teb( void *ptr, PEB *peb, BOOL is_wow ) if (is_wow) teb64->WowTebOffset = teb_offset; #else teb = (TEB *)teb32; - teb64->Peb = PtrToUlong( (char *)peb + page_size ); + teb64->Peb = PtrToUlong( (char *)peb - page_size ); teb64->Tib.Self = PtrToUlong( teb64 ); teb64->Tib.ExceptionList = PtrToUlong( teb32 ); teb64->ActivationContextStackPointer = PtrToUlong( &teb64->ActivationContextStack ); diff --git a/server/process.c b/server/process.c index 491ab3b7bbd..aab723114a8 100644 --- a/server/process.c +++ b/server/process.c @@ -1001,8 +1001,13 @@ void enum_processes( int (*cb)(struct process*, void*), void *user ) int set_process_debug_flag( struct process *process, int flag ) { char data = (flag != 0); + client_ptr_t peb32 = 0; + + if (!is_machine_64bit( process->machine ) && is_machine_64bit( supported_machines[0] )) + peb32 = process->peb + 0x1000; /* BeingDebugged flag is the byte at offset 2 in the PEB */ + if (peb32 && !write_process_memory( process, peb32 + 2, 1, &data )) return 0; return write_process_memory( process, process->peb + 2, 1, &data ); }