Rebase against 1719aef8cbc99994ec93848ae6e9e29e5c4beb78.

This commit is contained in:
Zebediah Figura 2024-03-08 17:40:23 -06:00
parent ec3dd19d45
commit 9e265ac738
9 changed files with 1 additions and 899 deletions

View File

@ -1,149 +0,0 @@
From 51cde3dff5de27d1aebc964a4802758534d56773 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
Date: Sat, 5 Aug 2017 03:39:55 +0200
Subject: [PATCH] ntdll: Implement process token elevation through manifests.
---
dlls/ntdll/loader.c | 37 +++++++++++++++++++++++++++++++++++++
server/process.c | 8 ++++++++
server/process.h | 1 +
server/protocol.def | 7 +++++++
server/token.c | 14 ++++++++++++++
5 files changed, 67 insertions(+)
diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c
index 6290cbcb4e6..9a8f13901b2 100644
--- a/dlls/ntdll/loader.c
+++ b/dlls/ntdll/loader.c
@@ -3489,6 +3489,32 @@ void WINAPI LdrInitializeThunk( CONTEXT *context, void **entry, ULONG_PTR unknow
}
+/***********************************************************************
+ * elevate_process
+ */
+static void elevate_process( void )
+{
+ NTSTATUS status;
+ HANDLE token;
+
+ if (!(token = __wine_create_default_token( TRUE )))
+ {
+ ERR( "Failed to create admin token\n" );
+ return;
+ }
+
+ SERVER_START_REQ( replace_process_token )
+ {
+ req->token = wine_server_obj_handle( token );
+ if ((status = wine_server_call( req )))
+ ERR( "Failed to replace process token: %08x\n", status );
+ }
+ SERVER_END_REQ;
+
+ NtClose( token );
+}
+
+
/***********************************************************************
* load_global_options
*/
@@ -3900,6 +3926,7 @@ void __wine_process_init(void)
'k','e','r','n','e','l','3','2','.','d','l','l',0};
void (WINAPI *kernel32_start_process)(LPTHREAD_START_ROUTINE,void*) = NULL;
RTL_USER_PROCESS_PARAMETERS *params;
+ ACTIVATION_CONTEXT_RUN_LEVEL_INFORMATION runlevel;
WINE_MODREF *wm;
NTSTATUS status;
ANSI_STRING func_name;
@@ -4021,6 +4048,16 @@ void __wine_process_init(void)
}
#endif
+ /* elevate process if necessary */
+ status = RtlQueryInformationActivationContext( 0, NULL, 0, RunlevelInformationInActivationContext,
+ &runlevel, sizeof(runlevel), NULL );
+ if (!status && (runlevel.RunLevel == ACTCTX_RUN_LEVEL_HIGHEST_AVAILABLE ||
+ runlevel.RunLevel == ACTCTX_RUN_LEVEL_REQUIRE_ADMIN))
+ {
+ TRACE( "Application requested admin rights (run level %d)\n", runlevel.RunLevel );
+ elevate_process(); /* FIXME: the process exists with a wrong token for a short time */
+ }
+
/* the main exe needs to be the first in the load order list */
RemoveEntryList( &wm->ldr.InLoadOrderLinks );
InsertHeadList( &peb->LdrData->InLoadOrderModuleList, &wm->ldr.InLoadOrderLinks );
diff --git a/server/process.c b/server/process.c
index fa8495511e0..df72efdecc8 100644
--- a/server/process.c
+++ b/server/process.c
@@ -1086,6 +1086,14 @@ int set_process_debug_flag( struct process *process, int flag )
return write_process_memory( process, process->peb + 2, 1, &data );
}
+/* replace the token of a process */
+void replace_process_token( struct process *process, struct token *new_token )
+{
+ release_object(current->process->token);
+ current->process->token = new_token;
+ grab_object(new_token);
+}
+
/* create a new process */
DECL_HANDLER(new_process)
{
diff --git a/server/process.h b/server/process.h
index 0fdf070b78e..43e8cc1ad7e 100644
--- a/server/process.h
+++ b/server/process.h
@@ -129,6 +129,7 @@ extern void kill_console_processes( struct thread *renderer, int exit_code );
extern void kill_debugged_processes( struct thread *debugger, int exit_code );
extern void detach_debugged_processes( struct thread *debugger );
extern void enum_processes( int (*cb)(struct process*, void*), void *user);
+extern void replace_process_token( struct process *process, struct token *token );
/* console functions */
extern obj_handle_t inherit_console( struct thread *parent_thread, obj_handle_t handle,
diff --git a/server/protocol.def b/server/protocol.def
index a9308904afc..8c40fba8d0a 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -3489,6 +3489,13 @@ struct handle_info
@END
+/* Create a new token */
+@REQ(replace_process_token)
+ obj_handle_t token; /* new process token */
+@REPLY
+@END
+
+
/* Create I/O completion port */
@REQ(create_completion)
unsigned int access; /* desired access to a port */
diff --git a/server/token.c b/server/token.c
index 970ed1838da..1c1d49989b3 100644
--- a/server/token.c
+++ b/server/token.c
@@ -1804,3 +1804,17 @@ DECL_HANDLER(create_token)
release_object( token );
}
}
+
+/* Replaces the token of the current process */
+DECL_HANDLER(replace_process_token)
+{
+ struct token *token;
+
+ if ((token = (struct token *)get_handle_obj( current->process, req->token,
+ TOKEN_ASSIGN_PRIMARY,
+ &token_ops )))
+ {
+ replace_process_token( current->process, token );
+ release_object( token );
+ }
+}
--
2.28.0

View File

@ -1,80 +0,0 @@
From baff5c160cf7f1ac0011bf8f55d506bf0346e1fd Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
Date: Mon, 7 Aug 2017 02:53:06 +0200
Subject: [PATCH] user32: Start explorer.exe using limited rights.
---
dlls/advapi32/tests/security.c | 4 ++--
dlls/user32/win.c | 12 ++++++++++--
2 files changed, 12 insertions(+), 4 deletions(-)
diff --git a/dlls/advapi32/tests/security.c b/dlls/advapi32/tests/security.c
index f27642e7a7..0271cd72e0 100644
--- a/dlls/advapi32/tests/security.c
+++ b/dlls/advapi32/tests/security.c
@@ -7313,7 +7313,7 @@ static void test_token_security_descriptor(void)
ret = GetTokenInformation(token4, TokenIntegrityLevel, buffer_integrity, sizeof(buffer_integrity), &size);
ok(ret, "GetTokenInformation failed with error %u\n", GetLastError());
tml = (TOKEN_MANDATORY_LABEL *)buffer_integrity;
- todo_wine ok(EqualSid(tml->Label.Sid, &medium_level), "Expected medium integrity level\n");
+ ok(EqualSid(tml->Label.Sid, &medium_level), "Expected medium integrity level\n");
size = 0;
ret = GetKernelObjectSecurity(token4, LABEL_SECURITY_INFORMATION, NULL, 0, &size);
@@ -7768,7 +7768,7 @@ static void test_child_token_sd_medium(void)
ret = GetTokenInformation(token, TokenIntegrityLevel, buffer_integrity, sizeof(buffer_integrity), &size);
ok(ret, "GetTokenInformation failed with error %u\n", GetLastError());
tml = (TOKEN_MANDATORY_LABEL *)buffer_integrity;
- todo_wine ok(EqualSid(tml->Label.Sid, &medium_level), "Expected medium integrity level\n");
+ ok(EqualSid(tml->Label.Sid, &medium_level), "Expected medium integrity level\n");
HeapFree(GetProcessHeap(), 0, sd);
}
diff --git a/dlls/user32/win.c b/dlls/user32/win.c
index cbfd8bb14a..8039f54fb0 100644
--- a/dlls/user32/win.c
+++ b/dlls/user32/win.c
@@ -43,6 +43,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(win);
#define NB_USER_HANDLES ((LAST_USER_HANDLE - FIRST_USER_HANDLE + 1) >> 1)
#define USER_HANDLE_TO_INDEX(hwnd) ((LOWORD(hwnd) - FIRST_USER_HANDLE) >> 1)
+extern HANDLE CDECL __wine_create_default_token(BOOL admin);
+
static DWORD process_layout = ~0u;
static struct list window_surfaces = LIST_INIT( window_surfaces );
@@ -2052,6 +2054,7 @@ HWND WINAPI GetDesktopWindow(void)
WCHAR app[MAX_PATH + ARRAY_SIZE( explorer )];
WCHAR cmdline[MAX_PATH + ARRAY_SIZE( explorer ) + ARRAY_SIZE( args )];
WCHAR desktop[MAX_PATH];
+ HANDLE token;
void *redir;
SERVER_START_REQ( set_user_object_info )
@@ -2084,9 +2087,12 @@ HWND WINAPI GetDesktopWindow(void)
strcpyW( cmdline, app );
strcatW( cmdline, args );
+ if (!(token = __wine_create_default_token( FALSE )))
+ ERR( "Failed to create limited token\n" );
+
Wow64DisableWow64FsRedirection( &redir );
- if (CreateProcessW( app, cmdline, NULL, NULL, FALSE, DETACHED_PROCESS,
- NULL, windir, &si, &pi ))
+ if (CreateProcessAsUserW( token, app, cmdline, NULL, NULL, FALSE, DETACHED_PROCESS,
+ NULL, windir, &si, &pi ))
{
TRACE( "started explorer pid %04x tid %04x\n", pi.dwProcessId, pi.dwThreadId );
WaitForInputIdle( pi.hProcess, 10000 );
@@ -2096,6 +2102,8 @@ HWND WINAPI GetDesktopWindow(void)
else WARN( "failed to start explorer, err %d\n", GetLastError() );
Wow64RevertWow64FsRedirection( redir );
+ if (token) CloseHandle( token );
+
SERVER_START_REQ( get_desktop_window )
{
req->force = 1;
--
2.18.0

View File

@ -1,344 +0,0 @@
From 5bf0baa79c46ec44dfd5e1340e96ff9289bc37f8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
Date: Sun, 6 Aug 2017 03:15:34 +0200
Subject: [PATCH] programs/runas: Basic implementation for starting processes
with a different trustlevel.
---
configure.ac | 1 +
programs/runas/Makefile.in | 8 ++
programs/runas/runas.c | 214 +++++++++++++++++++++++++++++++++++++
programs/runas/runas.h | 26 +++++
programs/runas/runas.rc | 39 +++++++
5 files changed, 288 insertions(+)
create mode 100644 programs/runas/Makefile.in
create mode 100644 programs/runas/runas.c
create mode 100644 programs/runas/runas.h
create mode 100644 programs/runas/runas.rc
diff --git a/configure.ac b/configure.ac
index 499c4f37ca..6f12614af1 100644
--- a/configure.ac
+++ b/configure.ac
@@ -3891,6 +3891,7 @@ WINE_CONFIG_MAKEFILE(programs/regedit/tests)
WINE_CONFIG_MAKEFILE(programs/regsvcs)
WINE_CONFIG_MAKEFILE(programs/regsvr32)
WINE_CONFIG_MAKEFILE(programs/rpcss)
+WINE_CONFIG_MAKEFILE(programs/runas)
WINE_CONFIG_MAKEFILE(programs/rundll.exe16,enable_win16)
WINE_CONFIG_MAKEFILE(programs/rundll32)
WINE_CONFIG_MAKEFILE(programs/sc)
diff --git a/programs/runas/Makefile.in b/programs/runas/Makefile.in
new file mode 100644
index 0000000000..33aa00ab03
--- /dev/null
+++ b/programs/runas/Makefile.in
@@ -0,0 +1,8 @@
+MODULE = runas.exe
+APPMODE = -mconsole -municode -mno-cygwin
+IMPORTS = advapi32 user32
+
+C_SRCS = \
+ runas.c
+
+RC_SRCS = runas.rc
diff --git a/programs/runas/runas.c b/programs/runas/runas.c
new file mode 100644
index 0000000000..412755afa0
--- /dev/null
+++ b/programs/runas/runas.c
@@ -0,0 +1,214 @@
+/*
+ * runas.exe implementation
+ *
+ * Copyright 2017 Michael Müller
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <windows.h>
+#include <wchar.h>
+#include <wine/debug.h>
+
+#include "runas.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(runas);
+
+extern HANDLE CDECL __wine_create_default_token(BOOL admin);
+
+struct cmdinfo
+{
+ WCHAR *program;
+ DWORD trustlevel;
+};
+
+static void output_writeconsole(const WCHAR *str, DWORD wlen)
+{
+ DWORD count, ret;
+
+ ret = WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), str, wlen, &count, NULL);
+ if (!ret)
+ {
+ DWORD len;
+ char *msgA;
+
+ /* On Windows WriteConsoleW() fails if the output is redirected. So fall
+ * back to WriteFile(), assuming the console encoding is still the right
+ * one in that case.
+ */
+ len = WideCharToMultiByte(GetConsoleOutputCP(), 0, str, wlen, NULL, 0, NULL, NULL);
+ msgA = HeapAlloc(GetProcessHeap(), 0, len * sizeof(char));
+ if (!msgA) return;
+
+ WideCharToMultiByte(GetConsoleOutputCP(), 0, str, wlen, msgA, len, NULL, NULL);
+ WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), msgA, len, &count, FALSE);
+ HeapFree(GetProcessHeap(), 0, msgA);
+ }
+}
+
+static void output_formatstring(const WCHAR *fmt, __ms_va_list va_args)
+{
+ WCHAR *str;
+ DWORD len;
+
+ SetLastError(NO_ERROR);
+ len = FormatMessageW(FORMAT_MESSAGE_FROM_STRING|FORMAT_MESSAGE_ALLOCATE_BUFFER,
+ fmt, 0, 0, (WCHAR *)&str, 0, &va_args);
+ if (len == 0 && GetLastError() != NO_ERROR)
+ {
+ WINE_FIXME("Could not format string: le=%u, fmt=%s\n", GetLastError(), wine_dbgstr_w(fmt));
+ return;
+ }
+ output_writeconsole(str, len);
+ LocalFree(str);
+}
+
+static void WINAPIV output_message(unsigned int id, ...)
+{
+ WCHAR fmt[1024];
+ __ms_va_list va_args;
+
+ if (!LoadStringW(GetModuleHandleW(NULL), id, fmt, sizeof(fmt)/sizeof(WCHAR)))
+ {
+ WINE_FIXME("LoadString failed with %d\n", GetLastError());
+ return;
+ }
+ __ms_va_start(va_args, id);
+ output_formatstring(fmt, va_args);
+ __ms_va_end(va_args);
+}
+
+static void show_usage(void)
+{
+ output_message(STRING_USAGE);
+}
+
+static void show_trustlevels(void)
+{
+ output_message(STRING_TRUSTLEVELS);
+ ExitProcess(0);
+}
+
+static WCHAR *starts_with(WCHAR *str, const WCHAR *start)
+{
+ DWORD start_len = lstrlenW(start);
+ if (lstrlenW(str) < start_len)
+ return NULL;
+ if (wcsncmp(str, start, start_len))
+ return NULL;
+ return str + start_len;
+}
+
+static BOOL parse_command_line(int argc, WCHAR *argv[], struct cmdinfo *cmd)
+{
+ static const WCHAR showtrustlevelsW[] = {'/','s','h','o','w','t','r','u','s','t','l','e','v','e','l','s',0};
+ static const WCHAR trustlevelW[] = {'/','t','r','u','s','t','l','e','v','e','l',':',0};
+ int i;
+
+ memset(cmd, 0, sizeof(*cmd));
+
+ for (i = 1; i < argc; i++)
+ {
+ if (argv[i][0] == '/')
+ {
+ WCHAR *arg;
+
+ if ((arg = starts_with(argv[i], trustlevelW)))
+ cmd->trustlevel = wcstoul(arg, NULL, 0);
+ else if (!lstrcmpW(argv[i], showtrustlevelsW))
+ show_trustlevels();
+ else
+ WINE_FIXME("Ignoring parameter %s\n", wine_dbgstr_w(argv[i]));
+ }
+ else if (argv[i][0])
+ {
+ if (cmd->program) return FALSE;
+ cmd->program = argv[i];
+ }
+ }
+
+ return TRUE;
+}
+
+static BOOL start_process(struct cmdinfo *cmd)
+{
+ PROCESS_INFORMATION info;
+ STARTUPINFOW startup;
+ HANDLE token = NULL;
+ BOOL ret;
+
+ if (cmd->trustlevel == 0x20000)
+ {
+ if (!(token = __wine_create_default_token(FALSE)))
+ ERR("Failed to create limited token\n");
+ }
+
+ memset(&startup, 0, sizeof(startup));
+ startup.cb = sizeof(startup);
+ ret = CreateProcessAsUserW(token, NULL, cmd->program, NULL, NULL, FALSE, 0, NULL, NULL, &startup, &info);
+ if (ret)
+ {
+ CloseHandle(info.hProcess);
+ CloseHandle(info.hThread);
+ }
+ else
+ {
+ DWORD error = GetLastError();
+ WCHAR *str;
+
+ if (FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_IGNORE_INSERTS, NULL, error, 0, (WCHAR *)&str, 0, NULL))
+ {
+ output_message(STRING_START_ERROR, cmd->program, error, str);
+ LocalFree(str);
+ }
+ else
+ WINE_FIXME("Failed to format error: %u\n", error);
+ }
+
+ if (token) CloseHandle(token);
+ return ret;
+}
+
+int wmain(int argc, WCHAR *argv[])
+{
+ struct cmdinfo cmd;
+
+ if (argc <= 1)
+ {
+ show_usage();
+ return 0;
+ }
+
+ if (!parse_command_line(argc, argv, &cmd))
+ {
+ show_usage();
+ return 1;
+ }
+
+ if (!cmd.program)
+ {
+ show_usage();
+ return 1;
+ }
+
+ if (cmd.trustlevel && cmd.trustlevel != 0x20000)
+ {
+ output_message(STRING_UNHANDLED_TRUSTLEVEL, cmd.trustlevel);
+ return 1;
+ }
+
+ return start_process(&cmd);
+}
diff --git a/programs/runas/runas.h b/programs/runas/runas.h
new file mode 100644
index 0000000000..40599a3b33
--- /dev/null
+++ b/programs/runas/runas.h
@@ -0,0 +1,26 @@
+/*
+ * runas.exe implementation
+ *
+ * Copyright 2017 Michael Müller
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <windef.h>
+
+#define STRING_USAGE 101
+#define STRING_UNHANDLED_TRUSTLEVEL 102
+#define STRING_TRUSTLEVELS 103
+#define STRING_START_ERROR 104
diff --git a/programs/runas/runas.rc b/programs/runas/runas.rc
new file mode 100644
index 0000000000..f9297a4479
--- /dev/null
+++ b/programs/runas/runas.rc
@@ -0,0 +1,39 @@
+/*
+ * runas.exe implementation
+ *
+ * Copyright 2017 Michael Müller
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "runas.h"
+
+#pragma makedep po
+
+LANGUAGE LANG_ENGLISH, SUBLANG_DEFAULT
+
+STRINGTABLE
+{
+ STRING_USAGE, "Usage of RUNAS:\n\n\
+\RUNAS /trustlevel:<trustlevel> program\n\n\
+\ /showtrustlevels Show possible trustlevels\n\
+\ /trustlevel <trustlevel> should be listed in /showtrustlevels\n\
+\ program Program to start\n\n"
+ STRING_UNHANDLED_TRUSTLEVEL, "runas: Unhandled trustlevel 0x%1!x!\n"
+ STRING_TRUSTLEVELS, "The following trustlevels are supported:\n\
+0x20000 (standard user)\n"
+ STRING_START_ERROR, "RUNAS-Error: %1 could not be started\n\
+ %2!u!: %3\n"
+}
--
2.23.0.rc1

View File

@ -1,27 +0,0 @@
From 9804dd77fd8c0ec56963306f409fea6b910bb48d Mon Sep 17 00:00:00 2001
From: Zebediah Figura <z.figura12@gmail.com>
Date: Sun, 7 Feb 2021 22:54:19 -0600
Subject: [PATCH] server: Create processes using a limited administrator token
by default.
Signed-off-by: Zebediah Figura <z.figura12@gmail.com>
---
server/process.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/server/process.c b/server/process.c
index 15387a2affa..3a8bbdbfb2e 100644
--- a/server/process.c
+++ b/server/process.c
@@ -664,7 +664,7 @@ struct process *create_process( int fd, struct process *parent, unsigned int fla
if (!parent)
{
process->handles = alloc_handle_table( process, 0 );
- process->token = token_create_admin( TRUE, -1, TokenElevationTypeFull, default_session_id );
+ process->token = token_create_admin( TRUE, -1, TokenElevationTypeLimited, default_session_id );
process->affinity = ~0;
}
else
--
2.30.2

View File

@ -1,57 +0,0 @@
From 643461bc989bd848363241dcfa04187e8d3a84d1 Mon Sep 17 00:00:00 2001
From: Zebediah Figura <z.figura12@gmail.com>
Date: Fri, 21 May 2021 21:52:06 -0500
Subject: [PATCH] ntdll: Always start the initial process through start.exe.
Signed-off-by: Zebediah Figura <z.figura12@gmail.com>
---
dlls/ntdll/unix/env.c | 26 +++-----------------------
1 file changed, 3 insertions(+), 23 deletions(-)
diff --git a/dlls/ntdll/unix/env.c b/dlls/ntdll/unix/env.c
index 30782a70eb0..959bafb28b7 100644
--- a/dlls/ntdll/unix/env.c
+++ b/dlls/ntdll/unix/env.c
@@ -1909,6 +1909,7 @@ static void init_peb( RTL_USER_PROCESS_PARAMETERS *params, void *module )
*/
static RTL_USER_PROCESS_PARAMETERS *build_initial_params( void **module )
{
+ static const char *args[] = { "start.exe", "/exec" };
static const WCHAR valueW[] = {'1',0};
static const WCHAR pathW[] = {'P','A','T','H'};
RTL_USER_PROCESS_PARAMETERS *params = NULL;
@@ -1937,29 +1938,8 @@ static RTL_USER_PROCESS_PARAMETERS *build_initial_params( void **module )
add_registry_environment( &env, &env_pos, &env_size );
env[env_pos++] = 0;
- status = load_main_exe( NULL, main_argv[1], curdir, 0, &image, module );
- if (!status)
- {
- char *loader;
-
- if (main_image_info.ImageCharacteristics & IMAGE_FILE_DLL) status = STATUS_INVALID_IMAGE_FORMAT;
- /* if we have to use a different loader, fall back to start.exe */
- if ((loader = get_alternate_wineloader( main_image_info.Machine )))
- {
- free( loader );
- status = STATUS_INVALID_IMAGE_FORMAT;
- }
- }
-
- if (status) /* try launching it through start.exe */
- {
- static const char *args[] = { "start.exe", "/exec" };
- free( image );
- if (*module) NtUnmapViewOfSection( GetCurrentProcess(), *module );
- load_start_exe( &image, module );
- prepend_argv( args, 2 );
- }
- else rebuild_argv();
+ load_start_exe( &image, module );
+ prepend_argv( args, 2 );
main_wargv = build_wargv( get_dos_path( image ));
cmdline = build_command_line( main_wargv );
--
2.40.1

View File

@ -1,110 +0,0 @@
From 1eaa73714299df810d22a727e8053679d5e89f64 Mon Sep 17 00:00:00 2001
From: Zebediah Figura <z.figura12@gmail.com>
Date: Sun, 18 Apr 2021 17:46:35 -0500
Subject: [PATCH] kernelbase: Elevate processes if requested in
CreateProcessInternal().
Signed-off-by: Zebediah Figura <z.figura12@gmail.com>
---
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 54a524abe04..7365bee9425 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"
@@ -431,6 +432,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.@)
*/
@@ -517,7 +566,7 @@ BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessInternalW( HANDLE token, const WCHAR
WCHAR *p, *tidy_cmdline = cmd_line;
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;
ULONG nt_flags = 0;
USHORT machine = 0;
NTSTATUS status;
@@ -629,6 +678,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, machine, handle_list, job_list );
switch (status)
@@ -670,7 +722,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.40.1

View File

@ -1,129 +0,0 @@
From 1754d90b8cc833d55e6d3f3de23cdf89dffd37aa Mon Sep 17 00:00:00 2001
From: Zebediah Figura <z.figura12@gmail.com>
Date: Sun, 18 Apr 2021 17:46:44 -0500
Subject: [PATCH] ntdll: Elevate processes if requested in
RtlCreateUserProcess().
Signed-off-by: Zebediah Figura <z.figura12@gmail.com>
---
dlls/ntdll/process.c | 81 +++++++++++++++++++++++++++++++++++++++++---
1 file changed, 76 insertions(+), 5 deletions(-)
diff --git a/dlls/ntdll/process.c b/dlls/ntdll/process.c
index dcdb26f81d1..ed1b2a20311 100644
--- a/dlls/ntdll/process.c
+++ b/dlls/ntdll/process.c
@@ -37,6 +37,11 @@
#include "wine/exception.h"
+/* we don't want to include winuser.h */
+#define CREATEPROCESS_MANIFEST_RESOURCE_ID ((ULONG_PTR)1)
+
+WINE_DEFAULT_DEBUG_CHANNEL(process);
+
/******************************************************************************
* RtlGetCurrentPeb [NTDLL.@]
*
@@ -89,6 +94,63 @@ NTSTATUS WINAPI RtlWow64EnableFsRedirectionEx( ULONG disable, ULONG *old_value )
}
+static BOOL image_needs_elevation( const UNICODE_STRING *path )
+{
+ ACTIVATION_CONTEXT_RUN_LEVEL_INFORMATION run_level;
+ UNICODE_STRING path0;
+ BOOL ret = FALSE;
+ HANDLE handle;
+ ACTCTXW ctx;
+
+ if (RtlDuplicateUnicodeString( 1, path, &path0 ))
+ return FALSE;
+
+ ctx.cbSize = sizeof(ctx);
+ ctx.dwFlags = ACTCTX_FLAG_RESOURCE_NAME_VALID;
+ ctx.lpSource = path0.Buffer;
+ ctx.lpResourceName = (const WCHAR *)CREATEPROCESS_MANIFEST_RESOURCE_ID;
+
+ if (RtlCreateActivationContext( &handle, &ctx ))
+ {
+ RtlFreeUnicodeString( &path0 );
+ 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 );
+ RtlFreeUnicodeString( &path0 );
+ 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;
+}
+
+
/**********************************************************************
* RtlWow64GetCurrentMachine (NTDLL.@)
*/
@@ -461,8 +523,15 @@ NTSTATUS WINAPI RtlCreateUserProcess( UNICODE_STRING *path, ULONG attributes,
PS_CREATE_INFO create_info;
ULONG_PTR buffer[offsetof( PS_ATTRIBUTE_LIST, Attributes[6] ) / sizeof(ULONG_PTR)];
PS_ATTRIBUTE_LIST *attr = (PS_ATTRIBUTE_LIST *)buffer;
+ HANDLE elevated_token = NULL;
+ NTSTATUS status;
UINT pos = 0;
+ /* It's not clear whether we should use path or &params->ImagePathName here,
+ * but Roblox Player tries to pass an empty string for the latter. */
+ if (!token && image_needs_elevation( path ))
+ token = elevated_token = get_elevated_token();
+
RtlNormalizeProcessParams( params );
attr->Attributes[pos].Attribute = PS_ATTRIBUTE_IMAGE_NAME;
@@ -509,11 +578,13 @@ NTSTATUS WINAPI RtlCreateUserProcess( UNICODE_STRING *path, ULONG attributes,
InitializeObjectAttributes( &process_attr, NULL, 0, NULL, process_descr );
InitializeObjectAttributes( &thread_attr, NULL, 0, NULL, thread_descr );
- return NtCreateUserProcess( &info->Process, &info->Thread, PROCESS_ALL_ACCESS, THREAD_ALL_ACCESS,
- &process_attr, &thread_attr,
- inherit ? PROCESS_CREATE_FLAGS_INHERIT_HANDLES : 0,
- THREAD_CREATE_FLAGS_CREATE_SUSPENDED, params,
- &create_info, attr );
+ status = NtCreateUserProcess( &info->Process, &info->Thread, PROCESS_ALL_ACCESS, THREAD_ALL_ACCESS,
+ &process_attr, &thread_attr,
+ inherit ? PROCESS_CREATE_FLAGS_INHERIT_HANDLES : 0,
+ THREAD_CREATE_FLAGS_CREATE_SUSPENDED, params, &create_info, attr );
+
+ if (elevated_token) NtClose( elevated_token );
+ return status;
}
/***********************************************************************
--
2.43.0

View File

@ -1,2 +0,0 @@
Fixes: [40613] Multiple applications require UAC implementation to run installer/app as a normal user instead of administrator (WhatsApp Desktop, Smartflix, Squirrel Installers, OneDrive)
Fixes: [39262] DiscordSetup.exe (.NET 4.5.2 app): Squirrell installer requires being run as unelevated process ('explorer.exe' should run unelevated by default with Vista+ setting)

View File

@ -1 +1 @@
934cfb86b5e2b485b4b90e1eeac4021733559591
1719aef8cbc99994ec93848ae6e9e29e5c4beb78