标题：access token
access token 访问令牌的概念
Windows操作系统安全性的一个概念。一个访问令牌包含了此登陆会话的安全信息。当用  用户权利指派户登陆时，系统创建一个访问令牌，然后以该用户身份运行的的所有进程都拥有该令牌的一个拷贝。该令牌唯一表示该用户、用户的组和用户的特权。系统使用令牌控制用户可以访问哪些安全对象，并控制用户执行相关系统操作的能力。有两种令牌：主令牌和模拟的令牌。主令牌是与进程相关的；模拟的令牌是与模拟令牌的线程相关的。
进程拥有某种令牌就表示它拥有某种特权。什么是特权呢？特权是指用户进程进行各种系统操作的权利。如：关机，加载设备驱动程序，改变系统时间也是一种特权。可以对用户或用户所在的组授予特权。见图。
WinNT定义的特权在WinNT.h头文件中定义了这些特权的名称：
#define SE_CREATE_TOKEN_NAME TEXT("SeCreateTokenPrivilege")
#define SE_ASSIGNPRIMARYTOKEN_NAME TEXT("SeAssignPrimaryTokenPrivilege")
#define SE_LOCK_MEMORY_NAME TEXT("SeLockMemoryPrivilege")
#define SE_INCREASE_QUOTA_NAME TEXT("SeIncreaseQuotaPrivilege")
#define SE_UNSOLICITED_INPUT_NAME TEXT("SeUnsolicitedInputPrivilege")
#define SE_MACHINE_ACCOUNT_NAME TEXT("SeMachineAccountPrivilege")
#define SE_TCB_NAME TEXT("SeTcbPrivilege")
#define SE_SECURITY_NAME TEXT("SeSecurityPrivilege")
#define SE_TAKE_OWNERSHIP_NAME TEXT("SeTakeOwnershipPrivilege")
#define SE_LOAD_DRIVER_NAME TEXT("SeLoadDriverPrivilege")
#define SE_SYSTEM_PROFILE_NAME TEXT("SeSystemProfilePrivilege")
#define SE_SYSTEMTIME_NAME TEXT("SeSystemtimePrivilege")
#define SE_PROF_SINGLE_PROCESS_NAME TEXT("SeProfileSingleProcessPrivilege")
#define SE_INC_BASE_PRIORITY_NAME TEXT("SeIncreaseBasePriorityPrivilege")
#define SE_CREATE_PAGEFILE_NAME TEXT("SeCreatePagefilePrivilege")
#define SE_CREATE_PERMANENT_NAME TEXT("SeCreatePermanentPrivilege")
#define SE_BACKUP_NAME TEXT("SeBackupPrivilege")
#define SE_RESTORE_NAME TEXT("SeRestorePrivilege")
#define SE_SHUTDOWN_NAME TEXT("SeShutdownPrivilege")
#define SE_DEBUG_NAME TEXT("SeDebugPrivilege")
#define SE_AUDIT_NAME TEXT("SeAuditPrivilege")
#define SE_SYSTEM_ENVIRONMENT_NAME TEXT("SeSystemEnvironmentPrivilege")
#define SE_CHANGE_NOTIFY_NAME TEXT("SeChangeNotifyPrivilege")
#define SE_REMOTE_SHUTDOWN_NAME TEXT("SeRemoteShutdownPrivilege")
#define SE_UNDOCK_NAME TEXT("SeUndockPrivilege")
#define SE_SYNC_AGENT_NAME TEXT("SeSyncAgentPrivilege")
#define SE_ENABLE_DELEGATION_NAME TEXT("SeEnableDelegationPrivilege")
#define SE_MANAGE_VOLUME_NAME TEXT("SeManageVolumePrivilege")
#define SE_IMPERSONATE_NAME TEXT("SeImpersonatePrivilege")
#define SE_CREATE_GLOBAL_NAME TEXT("SeCreateGlobalPrivilege")
#define SE_TRUSTED_CREDMAN_ACCESS_NAME TEXT("SeTrustedCredManAccessPrivilege")
#define SE_RELABEL_NAME TEXT("SeRelabelPrivilege")
#define SE_INC_WORKING_SET_NAME TEXT("SeIncreaseWorkingSetPrivilege")
#define SE_TIME_ZONE_NAME TEXT("SeTimeZonePrivilege")
#define SE_CREATE_SYMBOLIC_LINK_NAME TEXT("SeCreateSymbolicLinkPrivilege")
如何取得一个进程的访问令牌
通过API函数OpenProcessToken 取得进程令牌。其定义如下：
BOOL WINAPI OpenProcessToken( 
__in HANDLE ProcessHandle, //进程句柄。通过GetCurrentProcess函数取得当前进程句柄
__in DWORD DesiredAccess, //要对令牌进行何种操作。如TOKEN_ADJUST_PRIVILEGES用于调整权限
__out PHANDLE TokenHandle //进程令牌句柄
);
如下代码取得进程的令牌，并告诉系统我们想调整令牌的权限
HANDLE hToken;
if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, 
&hToken)) {
......
}对令牌可以进行的操作ValueMeaningTOKEN_ADJUST_DEFAULT改变令牌所有者、主组或访问控制列表DACLTOKEN_ADJUST_GROUPS改变令牌的组属性TOKEN_ADJUST_PRIVILEGESenable or disable 令牌的特权TOKEN_ADJUST_SESSIONID调整令牌的Session ID。进程需要 SE_TCB_NAME 特权.TOKEN_ASSIGN_PRIMARY为进程分配主令牌。需要 SE_ASSIGNPRIMARYTOKEN_NAME 特权TOKEN_DUPLICATE复制令牌TOKEN_EXECUTE合并 STANDARD_RIGHTS_EXECUTE 和 TOKEN_IMPERSONATE.TOKEN_IMPERSONATE附加一个模拟令牌到进程TOKEN_QUERY查询令牌TOKEN_QUERY_SOURCE查询令牌源TOKEN_READ合并 STANDARD_RIGHTS_READ 和TOKEN_QUERY.TOKEN_WRITE合并 STANDARD_RIGHTS_WRITE, TOKEN_ADJUST_PRIVILEGES, TOKEN_ADJUST_GROUPS, 和 TOKEN_ADJUST_DEFAULT.TOKEN_ALL_ACCESS合并所以可能的操作
与访问令牌关联的特权
TOKEN_PRIVILEGES
如何调整访问令牌的特权
取得特权的LUID值首先通过LookupPrivilegeValue函数取得某种特权的LUID，通过特权的名称查找特权的LUID。
BOOL WINAPI LookupPrivilegeValue( 
__in_opt LPCTSTR lpSystemName, //特权所在的系统名称，NULL表示本地系统
__in LPCTSTR lpName, //特权名称，在WInNT.h 中定义的特权名称
__out PLUID lpLuid //取得的特权的LUID
);
如下代码取得SE_DEBUG_NAME特权的LUID，并将特权属性设为SE_PRIVILEGE_ENABLED
TOKEN_PRIVILEGES tp;
tp.PrivilegeCount = 1;
LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tp.Privileges[0].Luid);
tp.Privileges[0].Attributes =SE_PRIVILEGE_ENABLED;调整令牌特权AdjustTokenPrivileges函数可以调整令牌的特权。函数定义如下：
BOOL WINAPI AdjustTokenPrivileges( 
__in HANDLE TokenHandle, //令牌句柄
__in BOOL DisableAllPrivileges, //是否禁用所有特权，如为TRUE，则忽略NewState参数
__in_opt PTOKEN_PRIVILEGES NewState,//调整为NewState结构定义的特权
__in DWORD BufferLength, //PreviousState 参数的字节大小
__out_opt PTOKEN_PRIVILEGES PreviousState, 可选，调整之前的TOKEN_PRIVILEGES结构体指针
__out_opt PDWORD ReturnLength //可选，返回的结构体的长度
);
//调用
AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(tp), NULL, NULL);
主令牌和模拟的令牌
主令牌是有windows内核创建并分配给进程的默认访问令牌。