调用API取得进程令牌特权

来源:互联网 发布:福冈软件银行鹰 编辑:程序博客网 时间:2024/04/20 16:33

为什么使用HANDLE OpenProcess(DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwProcessId)函数,当指定了访问权限为PROCESS_ALL_ACCESS时,对进程进行读写操作还是被禁止,即使是使用管理员权限也不行。可以通过下面的方法得到解决。

        使用OpenProcessToken(HANDLE ProcessHandle, DWORD DesiredAccess, PHANDLE TokenHandle)函数取得进程令牌句柄。
解释下参数:
ProcessHandle:欲打开访问令牌的进程句柄;
DesiredAccess:访问令牌的访问类型,比如:TOKEN_ADJUST_PRIVILEGES;
TokenHandle:接收令牌句柄的指针;

        得到TokenHandle后,调用AdjustTokenPrivileges(HANDLE TokenHandle, BOOL DisableAllPrivileges, PTOKEN_PRIVILEGES NewState, DWORD BufferLength, PTOKEN_PRIVILEGES PreviousState, PDWORD ReturnLength)函数修改进程令牌就可以了。
解释下参数:
TokenHandle:上一步得到的令牌句柄;
DisableAllPrivileges:指定是否禁用令牌特权,在这里我们可以选择False;
NewState:新的令牌特权,这是一个指向TOKEN_PRIVILEGES结构的指针,该结构的解释看下面;
BufferLength:PreviousState的大小,以字节表示,如果PreviousState为NULL,则其可以为NULL;
PreviousState:接收前一个TOKEN_PRIVILEGES,可以为NULL;
ReturnLength:PreviousState实际接收到的字节数,可以为NULL;

        下面解释下TOKEN_PRIVILEGES结构,该结构包含了一系列的访问令牌特权,其结构定义如下:
typedef struct _TOKEN_PRIVILEGES {
 DWORD PrivilegeCount;
 LUID_AND_ATTRIBUTES Privileges[ANYSIZE_ARRAY];
} TOKEN_PRIVILEGES, *PTOKEN_PRIVILEGES;
其成员如下:
PrivilegeCount:Privileges数组的元素个数;
Privileges:一个LUID_AND_ATTRIBUTES结构类型的数组,关于该结构的解释看下文;

        LUID_AND_ATTRIBUTES结构表示了一个LUID和它的属性。LUID意思是本地唯一标识符Locally Unique Identifier,其意思和GUID差不多,都是64位长,其区别是,GUID对于全局来说是唯一的,而LUID只是对于本地系统来说唯一就可以。
下面是它的定义:
typedef struct _LUID_AND_ATTRIBUTES {
 LUID Luid;
 DWORD Attributes;
} LUID_AND_ATTRIBUTES, *PLUID_AND_ATTRIBUTES
其成员为:
Luid:一个LUID值,关于该值如何得到,看下面的解释;
Attributes:可以是下面值的“或”组合;
SE_PRIVILEGE_ENABLED:启动特权;
SE_PRIVILEGE_ENABLED_BY_DEFAULT:默认启动特权;
SE_PRIVILEGE_REMOVED:移除特权;
SE_PRIVILEGE_USED_FOR_ACCESS:该特权用于得到对对象和服务的访问权限。
一般我们选择SE_PRIVILEGE_ENABLED就可以了。

        如何得到LUID,可以调用LookupPrivilegeValue(LPCTSTR lpSystemName, LPCTSTR lpName, PLUID lpLuid)函数。
其参数如下:
lpSystemName:系统名称,如果是本地系统,则可以是NULL;
lpName:特权名;如:SeSecurityPrivilege;
lpLuid:接收LUID的地址;
        当得到了lpLuid后,我们就可以调用AdjustTokenPrivileges()函数了。