提升进程权限

时间:2022-08-29 14:57:42
int GrantDebugPrivilege(WHCHAR* PriviledgeName)
{
HANDLE TokenHandle = NULL;
TOKEN_PRIVILEGES PrivilegesToken;  //特权令牌一种结构体
LUID v1; 
int iRet;

if (!OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &TokenHandle)) //使用windows函数API 将想要的操作写进令牌权限中
{
return FALSE;
}
}
if(!LookupPriviegeValue(NULL,SE_DEBUG_NAME,&v1)) //查询进程权限  得到LUID的值
{
CloseHandle(TokenHandle);
return 0;
}
PriviegesToken.PrivilegeCount = 1;
PriviegesToken.Privileges[0].Luid = v1; //权限的类型
PriviegesToken.Privileges[1].Attributes =SE_PRIVILAGE_ENABLED;
iRet =AdjustTokenPrivieges(TokenHandle,FALSE,&PrivilegesToken,sizeof(PrivilegesToken),NULL,NULL);//调整令牌权限 PrivilegesToken 用户想要的权限
CloseHandle(TokenHandle);
return iRet;


--------------------------------------------------------------------------------------------

typedef struct _TOKEN_PRIVILEGES { 
  DWORDPrivilegeCount; 
  LUID_AND_ATTRIBUTESPrivileges[]; 
} TOKEN_PRIVILEGES, *PTOKEN_PRIVILEGES;  

三种属性:
SE_PRIVILEGE_ENABLED
The privilege is enabled.
SE_PRIVILEGE_ENABLED_BY_DEFAULT
The privilege is enabled by default.
SE_PRIVILEGE_USED_FOR_ACCESS
The privilege was used to gain access to an object or service.This flag is used to identify the relevant privileges in a setpassed by a client application that may contain unnecessaryprivileges.


BOOL OpenProcessToken( 
HANDLE ProcessHandle, 
DWORD DesiredAccess, 
PHANDLE TokenHandle 
); 
第一参数是要修改访问权限的进程句柄;第三个参数就是返回的访问令牌指针;第二个参数指定你要进行的操作类型,如要修改令牌我们要指定第二个参数为TOKEN_ADJUST_PRIVILEGES(其它一些参数可参考PlatformSDK)。通过这个函数我们就可以得到当前进程的访问令牌的句柄(指定函数的第一个参数为GetCurrentProcess()就可以了)。

typedef struct _LUID_AND_ATTRIBUTES { 
LUID Luid; 
DWORD Attributes; 
} LUID_AND_ATTRIBUTES,*PLUID_AND_ATTRIBUTES 
第二个参数就指明了我们要进行的操作类型,有三个可选项:SE_PRIVILEGE_ENABLED、SE_PRIVILEGE_ENABLED_BY_DEFAULT、SE_PRIVILEGE_USED_FOR_ACCESS。要使能一个权限就指定Attributes为SE_PRIVILEGE_ENABLED。第一个参数就是指权限的类型,是一个LUID的值,LUID就是指locallyuniqueidentifier,我想GUID大家是比较熟悉的,和GUID的要求保证全局唯一不同,LUID只要保证局部唯一,就是指在系统的每一次运行期间保证是唯一的就可以了。另外和GUID相同的一点,LUID也是一个64位的值,相信大家都看过GUID那一大串的值,我们要怎么样才能知道一个权限对应的LUID值是多少呢?这就要用到另外一个API

函数LookupPrivilegevalue,其原形如下: 
BOOL LookupPrivilegevalue( 
LPCTSTR lpSystemName, // system name 
LPCTSTR lpName, // privilege name 
PLUID lpLuid // locally uniqueidentifier 
); 
第一个参数是系统的名称,如果是本地系统只要指明为NULL就可以了,第三个参数就是返回LUID的指针,第二个参数就是指明了权限的名称,如“SeDebugPrivilege”。在Winnt.h中还定义了一些权限名称的宏,如: 
#define SE_BACKUP_NAMETEXT("SeBackupPrivilege") 
#define SE_RESTORE_NAMETEXT("SeRestorePrivilege") 
#define SE_SHUTDOWN_NAMETEXT("SeShutdownPrivilege") 
#define SE_DEBUG_NAMETEXT("SeDebugPrivilege") 
这样通过这三个函数的调用,我们就可以用OpenProcess(PROCESS_ALL_ACCESS,FALSE,dwProcessID)来打获得任意进程的句柄,并且指定了所有的访问权。