超越管理员角色:确定权限提升状态
最初用于检测管理员状态的代码在识别权限提升方面能力有限,因为它没有考虑例如以管理员身份运行但未提升权限的情况。这使得管理员容易在未经适当授权的情况下执行敏感操作。
为了解决这个问题,需要一种更全面的方法来确定管理员状态和实际的提升级别。以下代码示例提供了一种解决方案:
<code class="language-csharp">using Microsoft.Win32; using System; using System.Diagnostics; using System.Runtime.InteropServices; using System.Security.Principal; public static class UacHelper { // 用于确定UAC状态的UAC注册表项和值 private const string uacRegistryKey = "Software\Microsoft\Windows\CurrentVersion\Policies\System"; private const string uacRegistryValue = "EnableLUA"; // 令牌访问和查询常量 private static uint STANDARD_RIGHTS_READ = 0x00020000; private static uint TOKEN_QUERY = 0x0008; private static uint TOKEN_READ = (STANDARD_RIGHTS_READ | TOKEN_QUERY); // 用于打开具有所需访问权限的进程令牌的函数 [DllImport("advapi32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] static extern bool OpenProcessToken(IntPtr ProcessHandle, UInt32 DesiredAccess, out IntPtr TokenHandle); // 用于获取令牌信息(例如提升级别)的函数 [DllImport("advapi32.dll", SetLastError = true)] public static extern bool GetTokenInformation(IntPtr TokenHandle, TOKEN_INFORMATION_CLASS TokenInformationClass, IntPtr TokenInformation, uint TokenInformationLength, out uint ReturnLength); // 用于检索提升类型的令牌信息类 public enum TOKEN_INFORMATION_CLASS { TokenElevationType = 9 } // 可能的提升级别 public enum TOKEN_ELEVATION_TYPE { TokenElevationTypeDefault = 1, TokenElevationTypeFull, TokenElevationTypeLimited } // 检查UAC是否启用 public static bool IsUacEnabled { get { using (var uacKey = Registry.LocalMachine.OpenSubKey(uacRegistryKey, false)) { return uacKey.GetValue(uacRegistryValue).Equals(1); } } } // 检查当前进程是否已提升 public static bool IsProcessElevated { get { if (IsUacEnabled) { // 当前进程令牌的句柄 IntPtr tokenHandle; // 尝试以读取访问权限打开进程令牌 if (!OpenProcessToken(Process.GetCurrentProcess().Handle, TOKEN_READ, out tokenHandle)) { throw new ApplicationException("无法获取进程令牌。Win32错误代码:" + Marshal.GetLastWin32Error()); } // 分配内存以存储提升信息 int elevationResultSize = Marshal.SizeOf((int)TOKEN_ELEVATION_TYPE.TokenElevationTypeDefault); IntPtr elevationTypePtr = Marshal.AllocHGlobal(elevationResultSize); // 从令牌中检索提升类型 uint returnedSize; bool success = GetTokenInformation(tokenHandle, TOKEN_INFORMATION_CLASS.TokenElevationType, elevationTypePtr, (uint)elevationResultSize, out returnedSize); // 检查操作是否成功 if (success) { // 从已分配的内存中读取提升类型 var elevationResult = (TOKEN_ELEVATION_TYPE)Marshal.ReadInt32(elevationTypePtr); // 判断进程是否具有完全提升权限 return elevationResult == TOKEN_ELEVATION_TYPE.TokenElevationTypeFull; } else { throw new ApplicationException("无法确定当前提升级别。"); } } else { // UAC未启用,依靠WindowsPrincipal检查管理员角色 WindowsIdentity identity = WindowsIdentity.GetCurrent(); WindowsPrincipal principal = new WindowsPrincipal(identity); return principal.IsInRole(WindowsBuiltInRole.Administrator); } } } }</code>
使用方法:
要使用此代码,只需调用IsProcessElevated
属性:
<code class="language-csharp">bool isElevated = UacHelper.IsProcessElevated;</code>
如果进程以完全权限提升,则返回true
,否则返回false
。此外,您可以使用IsUacEnabled
属性检查系统上是否启用了UAC。
以上是Windows下如何准确判断进程是否提权?的详细内容。更多信息请关注PHP中文网其他相关文章!