From ff04eb9f419a1917b12996e3c064bb7de7af3704 Mon Sep 17 00:00:00 2001 From: Luke Street Date: Sun, 5 Oct 2025 18:16:15 -0600 Subject: [PATCH] Fix OpenProcessToken pseudo-handle regression --- dll/advapi32/processthreadsapi.cpp | 8 +++++++- dll/kernel32/handleapi.cpp | 7 +++---- dll/kernel32/internal.h | 10 ++++++++++ dll/kernel32/processthreadsapi.cpp | 24 +++++++++--------------- dll/kernel32/wow64apiset.cpp | 4 +--- dll/ntdll.cpp | 3 +-- 6 files changed, 31 insertions(+), 25 deletions(-) diff --git a/dll/advapi32/processthreadsapi.cpp b/dll/advapi32/processthreadsapi.cpp index b41050b..21944b6 100644 --- a/dll/advapi32/processthreadsapi.cpp +++ b/dll/advapi32/processthreadsapi.cpp @@ -5,6 +5,7 @@ #include "errors.h" #include "handles.h" #include "internal.h" +#include "kernel32/internal.h" #include "processes.h" namespace advapi32 { @@ -16,7 +17,12 @@ BOOL WIN_FUNC OpenProcessToken(HANDLE ProcessHandle, DWORD DesiredAccess, PHANDL wibo::lastError = ERROR_INVALID_PARAMETER; return FALSE; } - auto obj = wibo::handles().getAs(ProcessHandle); + Pin obj; + if (kernel32::isPseudoCurrentProcessHandle(ProcessHandle)) { + obj = make_pin(getpid(), -1); + } else { + obj = wibo::handles().getAs(ProcessHandle); + } if (!obj) { wibo::lastError = ERROR_INVALID_HANDLE; return FALSE; diff --git a/dll/kernel32/handleapi.cpp b/dll/kernel32/handleapi.cpp index a70212c..57958b5 100644 --- a/dll/kernel32/handleapi.cpp +++ b/dll/kernel32/handleapi.cpp @@ -23,7 +23,7 @@ BOOL WIN_FUNC DuplicateHandle(HANDLE hSourceProcessHandle, HANDLE hSourceHandle, } auto validateProcessHandle = [&](HANDLE handle) -> bool { - if (reinterpret_cast(handle) == kPseudoCurrentProcessHandleValue) { + if (isPseudoCurrentProcessHandle(handle)) { return true; } auto proc = wibo::handles().getAs(handle); @@ -37,15 +37,14 @@ BOOL WIN_FUNC DuplicateHandle(HANDLE hSourceProcessHandle, HANDLE hSourceHandle, return FALSE; } - uintptr_t sourceHandleRaw = reinterpret_cast(hSourceHandle); - if (sourceHandleRaw == kPseudoCurrentProcessHandleValue) { + if (isPseudoCurrentProcessHandle(hSourceHandle)) { auto po = make_pin(getpid(), -1); auto handle = wibo::handles().alloc(std::move(po), 0, 0); DEBUG_LOG("DuplicateHandle: created process handle for current process -> %p\n", handle); *lpTargetHandle = handle; wibo::lastError = ERROR_SUCCESS; return TRUE; - } else if (sourceHandleRaw == kPseudoCurrentThreadHandleValue) { + } else if (isPseudoCurrentThreadHandle(hSourceHandle)) { auto th = make_pin(pthread_self()); auto handle = wibo::handles().alloc(std::move(th), 0, 0); DEBUG_LOG("DuplicateHandle: created thread handle for current thread -> %p\n", handle); diff --git a/dll/kernel32/internal.h b/dll/kernel32/internal.h index a2cf90e..5889897 100644 --- a/dll/kernel32/internal.h +++ b/dll/kernel32/internal.h @@ -166,6 +166,16 @@ struct HeapObject : public ObjectBase { inline constexpr uintptr_t kPseudoCurrentProcessHandleValue = static_cast(-1); inline constexpr uintptr_t kPseudoCurrentThreadHandleValue = static_cast(-2); +inline bool isPseudoCurrentProcessHandle(HANDLE h) { + uintptr_t rawHandle = reinterpret_cast(h); + return rawHandle == kPseudoCurrentProcessHandleValue; +} + +inline bool isPseudoCurrentThreadHandle(HANDLE h) { + uintptr_t rawHandle = reinterpret_cast(h); + return rawHandle == kPseudoCurrentThreadHandleValue; +} + void tryMarkExecutable(void *mem); void setLastErrorFromErrno(); diff --git a/dll/kernel32/processthreadsapi.cpp b/dll/kernel32/processthreadsapi.cpp index cf680e8..9eb4c2a 100644 --- a/dll/kernel32/processthreadsapi.cpp +++ b/dll/kernel32/processthreadsapi.cpp @@ -175,11 +175,6 @@ void *threadTrampoline(void *param) { return nullptr; } -inline bool isPseudoCurrentThreadHandle(HANDLE h) { - uintptr_t rawHandle = reinterpret_cast(h); - return rawHandle == kernel32::kPseudoCurrentThreadHandleValue; -} - } // namespace namespace kernel32 { @@ -237,9 +232,7 @@ BOOL WIN_FUNC GetProcessAffinityMask(HANDLE hProcess, PDWORD_PTR lpProcessAffini return FALSE; } - uintptr_t rawHandle = reinterpret_cast(hProcess); - bool isPseudoHandle = rawHandle == 0 || rawHandle == kPseudoCurrentProcessHandleValue; - if (!isPseudoHandle) { + if (!isPseudoCurrentProcessHandle(hProcess)) { auto obj = wibo::handles().getAs(hProcess); if (!obj) { wibo::lastError = ERROR_INVALID_HANDLE; @@ -271,9 +264,7 @@ BOOL WIN_FUNC SetProcessAffinityMask(HANDLE hProcess, DWORD_PTR dwProcessAffinit return FALSE; } - uintptr_t rawHandle = reinterpret_cast(hProcess); - bool isPseudoHandle = rawHandle == 0 || rawHandle == kPseudoCurrentProcessHandleValue; - if (!isPseudoHandle) { + if (!isPseudoCurrentProcessHandle(hProcess)) { auto obj = wibo::handles().getAs(hProcess); if (!obj) { wibo::lastError = ERROR_INVALID_HANDLE; @@ -332,7 +323,7 @@ void WIN_FUNC ExitProcess(UINT uExitCode) { BOOL WIN_FUNC TerminateProcess(HANDLE hProcess, UINT uExitCode) { HOST_CONTEXT_GUARD(); DEBUG_LOG("TerminateProcess(%p, %u)\n", hProcess, uExitCode); - if (hProcess == reinterpret_cast(static_cast(-1))) { + if (isPseudoCurrentProcessHandle(hProcess)) { exit(static_cast(uExitCode)); } auto process = wibo::handles().getAs(hProcess); @@ -372,6 +363,11 @@ BOOL WIN_FUNC GetExitCodeProcess(HANDLE hProcess, LPDWORD lpExitCode) { wibo::lastError = ERROR_INVALID_PARAMETER; return FALSE; } + if (isPseudoCurrentProcessHandle(hProcess)) { + *lpExitCode = STILL_ACTIVE; + wibo::lastError = ERROR_SUCCESS; + return TRUE; + } auto process = wibo::handles().getAs(hProcess); if (!process) { wibo::lastError = ERROR_INVALID_HANDLE; @@ -599,9 +595,7 @@ BOOL WIN_FUNC GetThreadTimes(HANDLE hThread, FILETIME *lpCreationTime, FILETIME return FALSE; } - bool isPseudoCurrentThread = reinterpret_cast(hThread) == kernel32::kPseudoCurrentThreadHandleValue || - hThread == nullptr || hThread == reinterpret_cast(static_cast(-1)); - if (!isPseudoCurrentThread) { + if (!isPseudoCurrentThreadHandle(hThread)) { DEBUG_LOG("GetThreadTimes: unsupported handle %p\n", hThread); wibo::lastError = ERROR_INVALID_HANDLE; return FALSE; diff --git a/dll/kernel32/wow64apiset.cpp b/dll/kernel32/wow64apiset.cpp index 90568a6..98a8097 100644 --- a/dll/kernel32/wow64apiset.cpp +++ b/dll/kernel32/wow64apiset.cpp @@ -34,9 +34,7 @@ BOOL WIN_FUNC IsWow64Process(HANDLE hProcess, PBOOL Wow64Process) { return FALSE; } - uintptr_t rawHandle = reinterpret_cast(hProcess); - bool isPseudoHandle = rawHandle == kPseudoCurrentProcessHandleValue; - if (!isPseudoHandle) { + if (!isPseudoCurrentProcessHandle(hProcess)) { if (!hProcess) { wibo::lastError = ERROR_INVALID_HANDLE; return FALSE; diff --git a/dll/ntdll.cpp b/dll/ntdll.cpp index fb09740..0cb04c1 100644 --- a/dll/ntdll.cpp +++ b/dll/ntdll.cpp @@ -78,8 +78,7 @@ constexpr ULONG kOsPlatformId = 2; // VER_PLATFORM_WIN32_NT constexpr BYTE kProductTypeWorkstation = 1; // VER_NT_WORKSTATION bool resolveProcessDetails(HANDLE processHandle, ProcessHandleDetails &details) { - uintptr_t rawHandle = reinterpret_cast(processHandle); - if (rawHandle == static_cast(-1)) { + if (kernel32::isPseudoCurrentProcessHandle(processHandle)) { details.pid = getpid(); details.exitCode = STILL_ACTIVE; details.peb = wibo::processPeb;