提升进程/程序权限(C#)

来源:互联网 发布:php旅游网站模板 编辑:程序博客网 时间:2024/06/06 02:49

对于一个进程或程序而言,有时我们需要提升其权限,从而实现一些特殊的功能。如:

① 当调用Windows API实现修改系统时间的功能,必须以管理员身份运行程序才能修改时间,那么是否有方法可以不以管理员身份运行也能成功修改时间?

② 当调用Windows API实现修改时区的功能,即使以管理员身份运行,也无法修改时区,那么如何才能成功修改时区?

通过Windows提供的一组API,我们可以提升进程的权限,从而能够实现上述功能,而且可以实现更多的功能。Windows提供了35种不同的权限可以赋予进程,用于实现不同的功能。


代码下载:点击打开链接


1. 提升进程权限的Windows API

[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]public static extern IntPtr GetCurrentProcess();[DllImport("Advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)][return: MarshalAs(UnmanagedType.Bool)]public static extern bool OpenProcessToken(IntPtr ProcessHandle, uint DesiredAccesss, out IntPtr TokenHandle);[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)][return: MarshalAs(UnmanagedType.Bool)]public static extern Boolean CloseHandle(IntPtr hObject);[DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)][return: MarshalAs(UnmanagedType.Bool)]public static extern bool LookupPrivilegeValue(string lpSystemName, string lpName, [MarshalAs(UnmanagedType.Struct)] ref LUID lpLuid);[DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)][return: MarshalAs(UnmanagedType.Bool)]public static extern bool AdjustTokenPrivileges(IntPtr TokenHandle, [MarshalAs(UnmanagedType.Bool)] bool DisableAllPrivileges, [MarshalAs(UnmanagedType.Struct)]ref TOKEN_PRIVILEGES NewState, uint BufferLength, IntPtr PreviousState, uint ReturnLength);

2. 相关结构struct类型

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]struct LUID{    public int LowPart;    public uint HighPart;}[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]struct LUID_AND_ATTRIBUTES{    public LUID Luid;    public uint Attributes;}[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]struct TOKEN_PRIVILEGES{    public int PrivilegeCount;    public LUID_AND_ATTRIBUTES Privilege;}

3. 调用Windows API实现权限授予和权限撤销

以下是一个简化版的授予/撤销修改时区权限(SeTimeZonePrivilege)的例子:

public const uint TOKEN_QUERY = 0x0008;public const uint TOKEN_ADJUST_PRIVILEGES = 0x0020;public const uint SE_PRIVILEGE_ENABLED = 0x00000002;// 授予权限public void grantTimeZonePrivilege(){    bool flag;    LUID locallyUniqueIdentifier = new LUID();    flag = LookupPrivilegeValue(null, "SeTimeZonePrivilege", ref locallyUniqueIdentifier);    TOKEN_PRIVILEGES tokenPrivileges = new TOKEN_PRIVILEGES();    tokenPrivileges.PrivilegeCount = 1;    LUID_AND_ATTRIBUTES luidAndAtt = new LUID_AND_ATTRIBUTES();    // luidAndAtt.Attributes should be SE_PRIVILEGE_ENABLED to enable privilege    luidAndAtt.Attributes = SE_PRIVILEGE_ENABLED;    luidAndAtt.Luid = locallyUniqueIdentifier;    tokenPrivileges.Privilege = luidAndAtt;    IntPtr tokenHandle = IntPtr.Zero;    flag = OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, out tokenHandle);    flag = AdjustTokenPrivileges(tokenHandle, false, ref tokenPrivileges, 1024, IntPtr.Zero, 0);    flag = CloseHandle(tokenHandle);}// 撤销权限public void revokeTimeZonePrivilege(){    bool flag;    LUID locallyUniqueIdentifier = new LUID();    LookupPrivilegeValue(null, "SeTimeZonePrivilege", ref locallyUniqueIdentifier);    TOKEN_PRIVILEGES tokenPrivileges = new TOKEN_PRIVILEGES();    tokenPrivileges.PrivilegeCount = 1;    LUID_AND_ATTRIBUTES luidAndAtt = new LUID_AND_ATTRIBUTES();    // luidAndAtt.Attributes should be none (not set) to disable privilege    luidAndAtt.Luid = locallyUniqueIdentifier;    tokenPrivileges.Privilege = luidAndAtt;    IntPtr tokenHandle = IntPtr.Zero;    flag = OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, out tokenHandle);    flag = AdjustTokenPrivileges(tokenHandle, false, ref tokenPrivileges, 1024, IntPtr.Zero, 0);    flag = CloseHandle(tokenHandle);}

4. 注意事项

① 上述示例代码做了很大的简化,在实际使用过程需要更多的对异常和错误的处理。

② 如果需要详细的授予/撤销权限的代码,可以访问链接:点击打开链接

③ 并不是所有的权限都能直接授权给进程,有些权限需要通过相关的设置(如修改系统时间等)才能授予给进程,具体操作如下:

       1) 组合键Win+R,输入secpol.msc,打开【本地安全策略】;

       2) 选择【本地策略】 — 【用户权限分配】,在这里可以查看到所有的权限(策略),通过向安全设置中添加用户或组Users,即可以使得该权限可以授予给进程;

       3) 重启计算机。

④ Windows提供的35种权限及其名称(msdn官网):点击打开链接

原创粉丝点击