private static void DisableSeDebug(IntPtr ProcessHandle) { if (!PInvoke.OpenProcessToken(ProcessHandle, PInvoke.TOKEN_QUERY | PInvoke.TOKEN_ADJUST_PRIVILEGES, out var TokenHandle)) { throw new Win32Exception(Marshal.GetLastWin32Error()); } var luidDebugPrivilege = new PInvoke.LUID(); if (!PInvoke.LookupPrivilegeValue(null, "SeDebugPrivilege", ref luidDebugPrivilege)) { throw new Win32Exception(Marshal.GetLastWin32Error()); } var RequiredPrivileges = new PInvoke.PRIVILEGE_SET { PrivilegeCount = 1, Control = PInvoke.PRIVILEGE_SET_ALL_NECESSARY, Privilege = new PInvoke.LUID_AND_ATTRIBUTES[1] }; RequiredPrivileges.Privilege[0].Luid = luidDebugPrivilege; RequiredPrivileges.Privilege[0].Attributes = PInvoke.SE_PRIVILEGE_ENABLED; if (!PInvoke.PrivilegeCheck(TokenHandle, ref RequiredPrivileges, out bool bResult)) { throw new Win32Exception(Marshal.GetLastWin32Error()); } if (bResult) // SeDebugPrivilege is enabled; try disabling it { var TokenPrivileges = new PInvoke.TOKEN_PRIVILEGES { PrivilegeCount = 1, Privileges = new PInvoke.LUID_AND_ATTRIBUTES[1] }; TokenPrivileges.Privileges[0].Luid = luidDebugPrivilege; TokenPrivileges.Privileges[0].Attributes = PInvoke.SE_PRIVILEGE_REMOVED; if (!PInvoke.AdjustTokenPrivileges(TokenHandle, false, ref TokenPrivileges, 0, IntPtr.Zero, 0)) { throw new Win32Exception(Marshal.GetLastWin32Error()); } } PInvoke.CloseHandle(TokenHandle); }
internal static void RestorePrivileges(SafeHandle processHandle, List <AccountPrivilege> privileges) { CheckWin32Result(PInvoke.OpenProcessToken(processHandle, TOKEN_ACCESS_MASK.TOKEN_ADJUST_PRIVILEGES, out var tokenHandle)); try { foreach (var priv in privileges.Where(priv => priv.Result == "ENABLED")) { if (!PInvoke.AdjustTokenPrivileges(tokenHandle, false, priv.ReplacedPrivilege, 0, null, null)) { logger.TraceEvent(TraceEventType.Error, 0, "Error while reverting the {0} privilege: 0x{1:x}", priv.PrivilegeName, Marshal.GetLastWin32Error()); } } } finally { tokenHandle.Dispose(); } }
internal static List <AccountPrivilege> EnablePrivileges(SafeHandle processHandle, string[] privilegeNames) { CheckWin32Result(PInvoke.OpenProcessToken(processHandle, TOKEN_ACCESS_MASK.TOKEN_QUERY | TOKEN_ACCESS_MASK.TOKEN_ADJUST_PRIVILEGES, out var tokenHandle)); try { return(privilegeNames.Select(privilegeName => { CheckWin32Result(PInvoke.LookupPrivilegeValue(null, privilegeName, out var luid)); var privileges = new TOKEN_PRIVILEGES { PrivilegeCount = 1, Privileges = new() { _0 = new LUID_AND_ATTRIBUTES { Luid = luid, Attributes = TOKEN_PRIVILEGES_ATTRIBUTES.SE_PRIVILEGE_ENABLED } } }; var previousPrivileges = new TOKEN_PRIVILEGES(); uint length = 0; if (PInvoke.AdjustTokenPrivileges(tokenHandle, false, privileges, (uint)Marshal.SizeOf(previousPrivileges), &previousPrivileges, &length)) { Debug.Assert(length == Marshal.SizeOf(previousPrivileges)); var result = Marshal.GetLastWin32Error() == (int)WIN32_ERROR.NO_ERROR ? "ENABLED" : "FAILED (privilege not available)"; return new AccountPrivilege(privilegeName, result, previousPrivileges); } else { var result = $"FAILED (error 0x{Marshal.GetLastWin32Error():x}"; return new AccountPrivilege(privilegeName, result, new TOKEN_PRIVILEGES { PrivilegeCount = 0 }); } }).ToList()); } finally { tokenHandle.Dispose(); } }