From 71aba24d166ee16f6ea52d1b63acabccf0532514 Mon Sep 17 00:00:00 2001 From: Zebediah Figura Date: Sun, 18 Apr 2021 17:46:35 -0500 Subject: [PATCH] kernelbase: Elevate processes if requested in CreateProcessInternal(). Signed-off-by: Zebediah Figura --- dlls/kernelbase/process.c | 57 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 55 insertions(+), 2 deletions(-) diff --git a/dlls/kernelbase/process.c b/dlls/kernelbase/process.c index 35381f409e9..e64076cb860 100644 --- a/dlls/kernelbase/process.c +++ b/dlls/kernelbase/process.c @@ -30,6 +30,7 @@ #include "winnls.h" #include "wincontypes.h" #include "winternl.h" +#include "winuser.h" #include "kernelbase.h" #include "wine/debug.h" @@ -414,6 +415,54 @@ BOOL WINAPI DECLSPEC_HOTPATCH CloseHandle( HANDLE handle ) } +static BOOL image_needs_elevation( const WCHAR *path ) +{ + ACTIVATION_CONTEXT_RUN_LEVEL_INFORMATION run_level; + BOOL ret = FALSE; + HANDLE handle; + ACTCTXW ctx; + + ctx.cbSize = sizeof(ctx); + ctx.dwFlags = ACTCTX_FLAG_RESOURCE_NAME_VALID; + ctx.lpSource = path; + ctx.lpResourceName = (const WCHAR *)CREATEPROCESS_MANIFEST_RESOURCE_ID; + + if (RtlCreateActivationContext( &handle, &ctx )) return FALSE; + + if (!RtlQueryInformationActivationContext( 0, handle, NULL, RunlevelInformationInActivationContext, + &run_level, sizeof(run_level), NULL )) + { + TRACE( "image requested run level %#x\n", run_level.RunLevel ); + if (run_level.RunLevel == ACTCTX_RUN_LEVEL_HIGHEST_AVAILABLE + || run_level.RunLevel == ACTCTX_RUN_LEVEL_REQUIRE_ADMIN) + ret = TRUE; + } + RtlReleaseActivationContext( handle ); + + return ret; +} + + +static HANDLE get_elevated_token(void) +{ + TOKEN_ELEVATION_TYPE type; + TOKEN_LINKED_TOKEN linked; + NTSTATUS status; + + if ((status = NtQueryInformationToken( GetCurrentThreadEffectiveToken(), + TokenElevationType, &type, sizeof(type), NULL ))) + return NULL; + + if (type == TokenElevationTypeFull) return NULL; + + if ((status = NtQueryInformationToken( GetCurrentThreadEffectiveToken(), + TokenLinkedToken, &linked, sizeof(linked), NULL ))) + return NULL; + + return linked.LinkedToken; +} + + /********************************************************************** * CreateProcessAsUserA (kernelbase.@) */ @@ -500,7 +549,7 @@ BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessInternalW( HANDLE token, const WCHAR WCHAR *p, *tidy_cmdline = cmd_line, *orig_app_name = NULL; RTL_USER_PROCESS_PARAMETERS *params = NULL; RTL_USER_PROCESS_INFORMATION rtl_info; - HANDLE parent = 0, debug = 0; + HANDLE parent = 0, debug = 0, elevated_token = NULL; const WCHAR *append; ULONG nt_flags = 0; NTSTATUS status; @@ -608,6 +657,9 @@ BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessInternalW( HANDLE token, const WCHAR if (flags & CREATE_BREAKAWAY_FROM_JOB) nt_flags |= PROCESS_CREATE_FLAGS_BREAKAWAY; if (flags & CREATE_SUSPENDED) nt_flags |= PROCESS_CREATE_FLAGS_SUSPENDED; + if (!token && image_needs_elevation( params->ImagePathName.Buffer )) + token = elevated_token = get_elevated_token(); + status = create_nt_process( token, debug, process_attr, thread_attr, nt_flags, params, &rtl_info, parent, handle_list, job_list ); switch (status) @@ -649,7 +701,8 @@ BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessInternalW( HANDLE token, const WCHAR TRACE( "started process pid %04lx tid %04lx\n", info->dwProcessId, info->dwThreadId ); } - done: +done: + if (elevated_token) NtClose( elevated_token ); RtlDestroyProcessParameters( params ); if (tidy_cmdline != cmd_line) HeapFree( GetProcessHeap(), 0, tidy_cmdline ); return set_ntstatus( status ); -- 2.34.1