|
|
- using System;
- using System.Collections.Generic;
- using System.ComponentModel;
- using System.Diagnostics;
- using System.IO;
- using System.Linq;
- using System.Reflection;
- using System.Runtime.ConstrainedExecution;
- using System.Runtime.InteropServices;
- using System.Security;
- using System.Text;
- using System.Threading;
- using System.Threading.Tasks;
- using Microsoft.Win32.SafeHandles;
- using TrustedUninstaller.Shared.Actions;
-
- namespace TrustedUninstaller.Shared
- {
- public class ProcessPrivilege
- {
- private static Win32.TokensEx.SafeTokenHandle userToken = new Win32.TokensEx.SafeTokenHandle(IntPtr.Zero);
- private static Win32.TokensEx.SafeTokenHandle elevatedUserToken = new Win32.TokensEx.SafeTokenHandle(IntPtr.Zero);
- private static Win32.TokensEx.SafeTokenHandle systemToken = new Win32.TokensEx.SafeTokenHandle(IntPtr.Zero);
- private static Win32.TokensEx.SafeTokenHandle impsersonatedSystemToken = new Win32.TokensEx.SafeTokenHandle(IntPtr.Zero);
- private static Win32.TokensEx.SafeTokenHandle lsassToken = new Win32.TokensEx.SafeTokenHandle(IntPtr.Zero);
-
- internal static void ResetTokens()
- {
- elevatedUserToken = new Win32.TokensEx.SafeTokenHandle(IntPtr.Zero);
- lsassToken = new Win32.TokensEx.SafeTokenHandle(IntPtr.Zero);
- systemToken = new Win32.TokensEx.SafeTokenHandle(IntPtr.Zero);
- impsersonatedSystemToken = new Win32.TokensEx.SafeTokenHandle(IntPtr.Zero);
- userToken = new Win32.TokensEx.SafeTokenHandle(IntPtr.Zero);
- }
-
- public static void StartPrivilegedTask(AugmentedProcess.Process process, Privilege privilege)
- {
- var tcs = StartThread(process, privilege);
- tcs.Task.Wait();
- for (int i = 0; tcs.Task.Result != null && i <= 3; i++)
- {
- ErrorLogger.WriteToErrorLog("Error launching privileged process: " + tcs.Task.Result.Message, tcs.Task.Result.StackTrace, "PrivilegedProcess Warning",
- Path.GetFileName(process.StartInfo.FileName));
- ResetTokens();
- Thread.Sleep(500 * i);
- tcs = StartThread(process, privilege);
- tcs.Task.Wait();
- }
-
- if (tcs.Task.Result != null)
- throw new SecurityException("Error launching privileged process.", tcs.Task.Result);
- }
-
- private static TaskCompletionSource<Exception> StartThread(AugmentedProcess.Process process, Privilege privilege)
- {
- var tcs = new TaskCompletionSource<Exception>();
- var thread = new Thread(() =>
- {
- try
- {
- switch (privilege)
- {
- case (Privilege.System):
- GetSystemToken();
- process.Start(AugmentedProcess.Process.CreateType.RawToken, ref systemToken);
- break;
- case (Privilege.CurrentUser):
- GetUserToken(true);
- process.Start(AugmentedProcess.Process.CreateType.UserToken, ref userToken);
- break;
- case (Privilege.CurrentUserElevated):
- GetElevatedUserToken();
- process.Start(AugmentedProcess.Process.CreateType.RawToken, ref elevatedUserToken);
- break;
- default:
- throw new ArgumentException("Unexpected.");
- }
- }
- catch (Exception e)
- {
- tcs.SetResult(e);
- return;
- }
-
- tcs.SetResult(null);
- });
- thread.Start();
- return tcs;
- }
-
- private static uint GetUserSession()
- {
- var sessionId = Win32.WTS.WTSGetActiveConsoleSessionId();
- if (sessionId != 0xFFFFFFFF) return sessionId;
- IntPtr pSessionInfo = IntPtr.Zero;
- Int32 count = 0;
- if (Win32.WTS.WTSEnumerateSessions((IntPtr)null, 0, 1, ref pSessionInfo, ref count) == 0)
- throw new Win32Exception(Marshal.GetLastWin32Error(), "Error enumerating user sessions.");
- Int32 dataSize = Marshal.SizeOf(typeof(Win32.WTS.WTS_SESSION_INFO));
- Int64 current = (Int64)pSessionInfo;
- for (int i = 0; i < count; i++)
- {
- Win32.WTS.WTS_SESSION_INFO si =
- (Win32.WTS.WTS_SESSION_INFO)Marshal.PtrToStructure((System.IntPtr)current,
- typeof(Win32.WTS.WTS_SESSION_INFO));
- current += dataSize;
- if (si.State == Win32.WTS.WTS_CONNECTSTATE_CLASS.WTSActive)
- {
- sessionId = (uint)si.SessionID;
- break;
- }
- }
- Win32.WTS.WTSFreeMemory(pSessionInfo);
- return sessionId;
- }
-
- private static void GetUserToken(bool getPrivileges)
- {
- if (getPrivileges)
- {
- GetSystemToken();
- var result = Win32.Tokens.ImpersonateLoggedOnUser(systemToken);
- if (!result)
- throw new Win32Exception(Marshal.GetLastWin32Error(), "Error impersonating system process token.");
-
- Win32.TokensEx.AdjustCurrentPrivilege(Win32.Tokens.SE_ASSIGNPRIMARYTOKEN_NAME);
- Win32.TokensEx.AdjustCurrentPrivilege(Win32.Tokens.SE_INCREASE_QUOTA_NAME);
- }
-
- if (userToken.DangerousGetHandle() != IntPtr.Zero)
- return;
-
- var sessionId = GetUserSession();
-
- if (Win32.WTS.WTSQueryUserToken(sessionId, out Win32.TokensEx.SafeTokenHandle wtsToken))
- {
- if (!Win32.Tokens.DuplicateTokenEx(wtsToken, Win32.Tokens.TokenAccessFlags.TOKEN_ALL_ACCESS,
- IntPtr.Zero,
- Win32.Tokens.SECURITY_IMPERSONATION_LEVEL.SecurityIdentification,
- Win32.Tokens.TOKEN_TYPE.TokenPrimary, out userToken))
- {
- throw new Win32Exception(Marshal.GetLastWin32Error(),
- "Failed to duplicate process token for lsass.");
- }
- return;
- }
- throw new Win32Exception(Marshal.GetLastWin32Error(), "Error fetching active user session token.");
- }
-
- private static void GetElevatedUserToken()
- {
- GetSystemToken();
- var result = Win32.Tokens.ImpersonateLoggedOnUser(systemToken);
-
- if (!result)
- throw new Win32Exception(Marshal.GetLastWin32Error(), "Error impersonating system process token.");
-
- if (lsassToken.DangerousGetHandle() == IntPtr.Zero)
- {
- var processHandle = Win32.Process.OpenProcess(Win32.Process.ProcessAccessFlags.QueryLimitedInformation, false, Process.GetProcessesByName("lsass").First().Id);
- if (!Win32.Tokens.OpenProcessToken(processHandle,
- Win32.Tokens.TokenAccessFlags.TOKEN_DUPLICATE |
- Win32.Tokens.TokenAccessFlags.TOKEN_ASSIGN_PRIMARY |
- Win32.Tokens.TokenAccessFlags.TOKEN_QUERY | Win32.Tokens.TokenAccessFlags.TOKEN_IMPERSONATE,
- out var tokenHandle))
- {
- Win32.CloseHandle(processHandle);
- throw new Win32Exception(Marshal.GetLastWin32Error(), "Failed to open process token for lsass.");
- }
-
- if (!Win32.Tokens.DuplicateTokenEx(tokenHandle, Win32.Tokens.TokenAccessFlags.TOKEN_ALL_ACCESS,
- IntPtr.Zero,
- Win32.Tokens.SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation,
- Win32.Tokens.TOKEN_TYPE.TokenImpersonation, out lsassToken))
- {
- Win32.CloseHandle(processHandle);
- throw new Win32Exception(Marshal.GetLastWin32Error(),
- "Failed to duplicate process token for lsass.");
- }
-
- Win32.CloseHandle(processHandle);
- }
-
-
- result = Win32.Tokens.ImpersonateLoggedOnUser(lsassToken);
- if (!result)
- throw new Win32Exception(Marshal.GetLastWin32Error(), "Error impersonating lsass process token.");
-
-
- Win32.TokensEx.AdjustCurrentPrivilege(Win32.Tokens.SE_ASSIGNPRIMARYTOKEN_NAME);
- Win32.TokensEx.AdjustCurrentPrivilege(Win32.Tokens.SE_INCREASE_QUOTA_NAME);
-
-
- if (elevatedUserToken.DangerousGetHandle() != IntPtr.Zero)
- return;
-
-
- var privileges = new[]
- {
- Win32.Tokens.SE_INCREASE_QUOTA_NAME,
- Win32.Tokens.SE_MACHINE_ACCOUNT_NAME, Win32.Tokens.SE_SECURITY_NAME,
- Win32.Tokens.SE_TAKE_OWNERSHIP_NAME, Win32.Tokens.SE_LOAD_DRIVER_NAME,
- Win32.Tokens.SE_SYSTEM_PROFILE_NAME, Win32.Tokens.SE_SYSTEMTIME_NAME,
- Win32.Tokens.SE_PROFILE_SINGLE_PROCESS_NAME, Win32.Tokens.SE_INCREASE_BASE_PRIORITY_NAME,
- Win32.Tokens.SE_CREATE_PERMANENT_NAME,
- Win32.Tokens.SE_BACKUP_NAME, Win32.Tokens.SE_RESTORE_NAME, Win32.Tokens.SE_SHUTDOWN_NAME,
- Win32.Tokens.SE_DEBUG_NAME, Win32.Tokens.SE_AUDIT_NAME, Win32.Tokens.SE_SYSTEM_ENVIRONMENT_NAME,
- Win32.Tokens.SE_CHANGE_NOTIFY_NAME,
- Win32.Tokens.SE_UNDOCK_NAME, Win32.Tokens.SE_SYNC_AGENT_NAME,
- Win32.Tokens.SE_ENABLE_DELEGATION_NAME, Win32.Tokens.SE_MANAGE_VOLUME_NAME,
- Win32.Tokens.SE_IMPERSONATE_NAME, Win32.Tokens.SE_CREATE_GLOBAL_NAME,
- Win32.Tokens.SE_TRUSTED_CREDMAN_ACCESS_NAME, Win32.Tokens.SE_RELABEL_NAME,
- Win32.Tokens.SE_TIME_ZONE_NAME,
- Win32.Tokens.SE_CREATE_SYMBOLIC_LINK_NAME, Win32.Tokens.SE_DELEGATE_SESSION_USER_IMPERSONATE_NAME
- };
- var authId = Win32.Tokens.SYSTEM_LUID;
-
- GetUserToken(false);
-
- Win32.Tokens.DuplicateTokenEx(userToken,
- Win32.Tokens.TokenAccessFlags.TOKEN_ALL_ACCESS, IntPtr.Zero,
- Win32.Tokens.SECURITY_IMPERSONATION_LEVEL.SecurityIdentification, Win32.Tokens.TOKEN_TYPE.TokenPrimary,
- out Win32.TokensEx.SafeTokenHandle dupedUserToken);
-
- Win32.SID.AllocateAndInitializeSid(
- ref Win32.SID.SECURITY_MANDATORY_LABEL_AUTHORITY,
- 1,
- (int)Win32.SID.SECURITY_MANDATORY_LABEL.High,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- out IntPtr integritySid);
-
- var tokenMandatoryLabel = new Win32.Tokens.TOKEN_MANDATORY_LABEL() {
- Label = default(Win32.SID.SID_AND_ATTRIBUTES)
- };
-
- tokenMandatoryLabel.Label.Attributes = (uint)Win32.Tokens.SE_GROUP_ATTRIBUTES.SE_GROUP_INTEGRITY;
- tokenMandatoryLabel.Label.Sid = integritySid;
-
- var integritySize = Marshal.SizeOf(tokenMandatoryLabel);
- var tokenInfo = Marshal.AllocHGlobal(integritySize);
-
- Marshal.StructureToPtr(tokenMandatoryLabel, tokenInfo, false);
-
- Win32.Tokens.SetTokenInformation(
- dupedUserToken,
- Win32.Tokens.TOKEN_INFORMATION_CLASS.TokenIntegrityLevel,
- tokenInfo,
- integritySize + Win32.SID.GetLengthSid(integritySid));
-
-
- var pTokenUser = Win32.TokensEx.GetInfoFromToken(dupedUserToken, Win32.Tokens.TOKEN_INFORMATION_CLASS.TokenUser);
- var pTokenOwner =
- Win32.TokensEx.GetInfoFromToken(dupedUserToken, Win32.Tokens.TOKEN_INFORMATION_CLASS.TokenOwner);
- var pTokenPrivileges =
- Win32.TokensEx.GetInfoFromToken(dupedUserToken, Win32.Tokens.TOKEN_INFORMATION_CLASS.TokenPrivileges);
- var pTokenGroups =
- Win32.TokensEx.GetInfoFromToken(dupedUserToken, Win32.Tokens.TOKEN_INFORMATION_CLASS.TokenGroups);
- var pTokenPrimaryGroup =
- Win32.TokensEx.GetInfoFromToken(dupedUserToken, Win32.Tokens.TOKEN_INFORMATION_CLASS.TokenPrimaryGroup);
- var pTokenDefaultDacl =
- Win32.TokensEx.GetInfoFromToken(dupedUserToken, Win32.Tokens.TOKEN_INFORMATION_CLASS.TokenDefaultDacl);
- var pTokenSource =
- Win32.TokensEx.GetInfoFromToken(dupedUserToken, Win32.Tokens.TOKEN_INFORMATION_CLASS.TokenSource);
-
- var tokenUser =
- (Win32.Tokens.TOKEN_USER)Marshal.PtrToStructure(pTokenUser, typeof(Win32.Tokens.TOKEN_USER));
- if (!Win32.TokensEx.CreateTokenPrivileges(privileges, out var tokenPrivileges))
- tokenPrivileges =
- (Win32.Tokens.TOKEN_PRIVILEGES)Marshal.PtrToStructure(pTokenPrivileges,
- typeof(Win32.Tokens.TOKEN_PRIVILEGES));
- var tokenGroups = (Win32.Tokens.TOKEN_GROUPS)Marshal.PtrToStructure(
- pTokenGroups, typeof(Win32.Tokens.TOKEN_GROUPS));
- var tokenOwner =
- (Win32.Tokens.TOKEN_OWNER)Marshal.PtrToStructure(pTokenOwner, typeof(Win32.Tokens.TOKEN_OWNER));
- var tokenPrimaryGroup =
- (Win32.Tokens.TOKEN_PRIMARY_GROUP)Marshal.PtrToStructure(pTokenPrimaryGroup,
- typeof(Win32.Tokens.TOKEN_PRIMARY_GROUP));
- var tokenDefaultDacl = (Win32.Tokens.TOKEN_DEFAULT_DACL)Marshal.PtrToStructure(
- pTokenDefaultDacl, typeof(Win32.Tokens.TOKEN_DEFAULT_DACL));
- var tokenSource = (Win32.Tokens.TOKEN_SOURCE)Marshal.PtrToStructure(
- pTokenSource, typeof(Win32.Tokens.TOKEN_SOURCE));
- /*
- for (var idx = 0; idx < tokenPrivileges.PrivilegeCount - 1; idx++)
- {
- if ((tokenPrivileges.Privileges[idx].Attributes &
- (uint)Win32.Tokens.SE_PRIVILEGE_ATTRIBUTES.SE_PRIVILEGE_ENABLED) != 0)
- {
- }
-
- if ((tokenPrivileges.Privileges[idx].Attributes &
- (uint)Win32.Tokens.SE_PRIVILEGE_ATTRIBUTES.SE_PRIVILEGE_ENABLED_BY_DEFAULT) != 0)
- {
- }
- }
- */
-
- IntPtr adminsSid = IntPtr.Zero;
- IntPtr localAndAdminSid = IntPtr.Zero;
-
- bool adminsFound = false;
- bool localAndAdminFound = false;
-
- for (var idx = 0; idx < tokenGroups.GroupCount - 1; idx++)
- {
- Win32.SID.ConvertSidToStringSid(tokenGroups.Groups[idx].Sid, out string strSid);
- if (string.Compare(strSid, Win32.SID.DOMAIN_ALIAS_RID_ADMINS, StringComparison.OrdinalIgnoreCase) == 0)
- {
- adminsFound = true;
- tokenGroups.Groups[idx].Attributes = (uint)Win32.Tokens.SE_GROUP_ATTRIBUTES.SE_GROUP_ENABLED |
- (uint)Win32.Tokens.SE_GROUP_ATTRIBUTES
- .SE_GROUP_ENABLED_BY_DEFAULT | (uint)Win32.Tokens.SE_GROUP_ATTRIBUTES.SE_GROUP_MANDATORY | (uint)Win32.Tokens.SE_GROUP_ATTRIBUTES.SE_GROUP_OWNER;
- } else if (string.Compare(strSid, Win32.SID.DOMAIN_ALIAS_RID_LOCAL_AND_ADMIN_GROUP, StringComparison.OrdinalIgnoreCase) == 0)
- {
- localAndAdminFound = true;
- tokenGroups.Groups[idx].Attributes = (uint)Win32.Tokens.SE_GROUP_ATTRIBUTES.SE_GROUP_ENABLED |
- (uint)Win32.Tokens.SE_GROUP_ATTRIBUTES
- .SE_GROUP_ENABLED_BY_DEFAULT | (uint)Win32.Tokens.SE_GROUP_ATTRIBUTES.SE_GROUP_MANDATORY;
- }
- }
-
- if (!adminsFound)
- {
- Win32.SID.ConvertStringSidToSid(Win32.SID.DOMAIN_ALIAS_RID_ADMINS, out adminsSid);
- tokenGroups.Groups[tokenGroups.GroupCount].Sid = adminsSid;
- tokenGroups.Groups[tokenGroups.GroupCount].Attributes =
- (uint)Win32.Tokens.SE_GROUP_ATTRIBUTES.SE_GROUP_ENABLED |
- (uint)Win32.Tokens.SE_GROUP_ATTRIBUTES.SE_GROUP_ENABLED_BY_DEFAULT;
- tokenGroups.GroupCount++;
- }
- if (!localAndAdminFound)
- {
- Win32.SID.ConvertStringSidToSid(Win32.SID.DOMAIN_ALIAS_RID_LOCAL_AND_ADMIN_GROUP, out localAndAdminSid);
- tokenGroups.Groups[tokenGroups.GroupCount].Sid = localAndAdminSid;
- tokenGroups.Groups[tokenGroups.GroupCount].Attributes =
- (uint)Win32.Tokens.SE_GROUP_ATTRIBUTES.SE_GROUP_ENABLED |
- (uint)Win32.Tokens.SE_GROUP_ATTRIBUTES.SE_GROUP_ENABLED_BY_DEFAULT;
- tokenGroups.GroupCount++;
- }
-
- var expirationTime = new Win32.LARGE_INTEGER() { QuadPart = -1L };
- var sqos = new Win32.Tokens.SECURITY_QUALITY_OF_SERVICE(
- Win32.Tokens.SECURITY_IMPERSONATION_LEVEL.SecurityIdentification, Win32.Tokens.SECURITY_STATIC_TRACKING,
- 0);
- var oa = new Win32.Tokens.OBJECT_ATTRIBUTES(string.Empty, 0) { };
- var pSqos = Marshal.AllocHGlobal(Marshal.SizeOf(sqos));
- Marshal.StructureToPtr(sqos, pSqos, true);
- oa.SecurityQualityOfService = pSqos;
-
- var status = Win32.Tokens.ZwCreateToken(out elevatedUserToken,
- Win32.Tokens.TokenAccessFlags.TOKEN_ALL_ACCESS, ref oa, Win32.Tokens.TOKEN_TYPE.TokenPrimary,
- ref authId, ref expirationTime, ref tokenUser, ref tokenGroups, ref tokenPrivileges, ref tokenOwner,
- ref tokenPrimaryGroup, ref tokenDefaultDacl, ref tokenSource);
-
- Win32.LocalFree(pTokenUser);
- Win32.LocalFree(pTokenOwner);
- Win32.LocalFree(pTokenGroups);
- Win32.LocalFree(pTokenDefaultDacl);
- Win32.LocalFree(pTokenPrivileges);
- Win32.LocalFree(pTokenPrimaryGroup);
-
- if (adminsSid != IntPtr.Zero)
- Win32.SID.FreeSid(adminsSid);
- if (localAndAdminSid != IntPtr.Zero)
- Win32.SID.FreeSid(localAndAdminSid);
- if (integritySid != IntPtr.Zero)
- Win32.SID.FreeSid(integritySid);
-
- if (status != 0)
- throw new Win32Exception(Marshal.GetLastWin32Error(), "Error creating elevated user token: " + status);
- }
-
- public static void GetSystemToken()
- {
- if (systemToken.DangerousGetHandle() != IntPtr.Zero)
- return;
-
- try
- {
- var processHandle = Win32.Process.OpenProcess(Win32.Process.ProcessAccessFlags.QueryLimitedInformation, false, Process.GetProcessesByName("winlogon").First().Id);
- if (!Win32.Tokens.OpenProcessToken(processHandle,
- Win32.Tokens.TokenAccessFlags.TOKEN_DUPLICATE | Win32.Tokens.TokenAccessFlags.TOKEN_ASSIGN_PRIMARY |
- Win32.Tokens.TokenAccessFlags.TOKEN_QUERY | Win32.Tokens.TokenAccessFlags.TOKEN_IMPERSONATE,
- out var tokenHandle))
- {
- Win32.CloseHandle(processHandle);
- throw new Win32Exception(Marshal.GetLastWin32Error(), "Failed to open process token for winlogon.");
- }
-
- if (!Win32.Tokens.DuplicateTokenEx(tokenHandle, Win32.Tokens.TokenAccessFlags.TOKEN_ALL_ACCESS, IntPtr.Zero,
- Win32.Tokens.SECURITY_IMPERSONATION_LEVEL.SecurityIdentification,
- Win32.Tokens.TOKEN_TYPE.TokenPrimary, out systemToken))
- {
- Win32.CloseHandle(processHandle);
- throw new Win32Exception(Marshal.GetLastWin32Error(),
- "Failed to duplicate process token for winlogon.");
- }
-
- Win32.CloseHandle(processHandle);
- }
- catch (Exception e)
- {
- var sessionId = GetUserSession();
- int dwLsassPID = -1;
- int dwWinLogonPID = -1;
- Win32.WTS.WTS_PROCESS_INFO[] pProcesses;
- IntPtr pProcessInfo = IntPtr.Zero;
- int dwProcessCount = 0;
- if (Win32.WTS.WTSEnumerateProcesses((IntPtr)null, 0, 1, ref pProcessInfo, ref dwProcessCount))
- {
- IntPtr pMemory = pProcessInfo;
- pProcesses = new Win32.WTS.WTS_PROCESS_INFO[dwProcessCount];
- for (int i = 0; i < dwProcessCount; i++)
- {
- pProcesses[i] =
- (Win32.WTS.WTS_PROCESS_INFO)Marshal.PtrToStructure(pProcessInfo,
- typeof(Win32.WTS.WTS_PROCESS_INFO));
- pProcessInfo = (IntPtr)((long)pProcessInfo + Marshal.SizeOf(pProcesses[i]));
- var processName = Marshal.PtrToStringAnsi(pProcesses[i].ProcessName);
- Win32.SID.ConvertSidToStringSid(pProcesses[i].UserSid, out string sid);
- string strSid;
- if (processName == null || pProcesses[i].UserSid == default || sid != "S-1-5-18") continue;
- if ((-1 == dwLsassPID) && (0 == pProcesses[i].SessionID) && (processName == "lsass.exe"))
- {
- dwLsassPID = pProcesses[i].ProcessID;
- continue;
- }
-
- if ((-1 == dwWinLogonPID) && (sessionId == pProcesses[i].SessionID) &&
- (processName == "winlogon.exe"))
- {
- dwWinLogonPID = pProcesses[i].ProcessID;
- continue;
- }
- }
-
- Win32.WTS.WTSFreeMemory(pMemory);
- }
-
- IntPtr systemProcessHandle = IntPtr.Zero;
- try
- {
- systemProcessHandle = Process.GetProcessById(dwLsassPID).Handle;
- }
- catch
- {
- systemProcessHandle = Process.GetProcessById(dwWinLogonPID).Handle;
- }
-
- if (!Win32.Tokens.OpenProcessToken(systemProcessHandle, Win32.Tokens.TokenAccessFlags.TOKEN_DUPLICATE,
- out Win32.TokensEx.SafeTokenHandle token))
- {
- Win32.CloseHandle(systemProcessHandle);
- throw new Win32Exception(Marshal.GetLastWin32Error(), "Failed to open process token.");
- }
-
- if (!Win32.Tokens.DuplicateTokenEx(token, Win32.Tokens.TokenAccessFlags.MAXIMUM_ALLOWED, IntPtr.Zero,
- Win32.Tokens.SECURITY_IMPERSONATION_LEVEL.SecurityIdentification,
- Win32.Tokens.TOKEN_TYPE.TokenPrimary, out systemToken))
- {
- Win32.CloseHandle(systemProcessHandle);
- throw new Win32Exception(Marshal.GetLastWin32Error(), "Failed to duplicate process token.");
- }
-
- Win32.CloseHandle(systemProcessHandle);
- }
- }
-
- public static Win32.TokensEx.SafeTokenHandle GetCurrentProcessToken()
- {
- if (!Win32.Tokens.OpenProcessToken(Win32.Process.GetCurrentProcess(),
- Win32.Tokens.TokenAccessFlags.TOKEN_READ, out Win32.TokensEx.SafeTokenHandle token))
- throw new Win32Exception(Marshal.GetLastWin32Error(), "Error opening token for current process.");
- return token;
- }
-
- private static Win32.TokensEx.SafeTokenHandle GetProcessTokenByName(string name, bool impersonation)
- {
- var processHandle = Process.GetProcessesByName(name).First().Handle;
- if (!Win32.Tokens.OpenProcessToken(processHandle,
- Win32.Tokens.TokenAccessFlags.TOKEN_DUPLICATE | Win32.Tokens.TokenAccessFlags.TOKEN_ASSIGN_PRIMARY |
- Win32.Tokens.TokenAccessFlags.TOKEN_QUERY | Win32.Tokens.TokenAccessFlags.TOKEN_IMPERSONATE,
- out var tokenHandle))
- {
- Win32.CloseHandle(processHandle);
- throw new Win32Exception(Marshal.GetLastWin32Error(), "Failed to open process token for " + name + ".");
- }
-
- if (!Win32.Tokens.DuplicateTokenEx(tokenHandle, Win32.Tokens.TokenAccessFlags.TOKEN_ALL_ACCESS, IntPtr.Zero,
- impersonation ? Win32.Tokens.SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation : Win32.Tokens.SECURITY_IMPERSONATION_LEVEL.SecurityIdentification,
- impersonation ? Win32.Tokens.TOKEN_TYPE.TokenImpersonation : Win32.Tokens.TOKEN_TYPE.TokenPrimary, out Win32.TokensEx.SafeTokenHandle handle))
- {
- Win32.CloseHandle(processHandle);
- throw new Win32Exception(Marshal.GetLastWin32Error(),
- "Failed to duplicate process token for " + name + ".");
- }
-
- Win32.CloseHandle(processHandle);
- return handle;
- } }
- }
|