Token中有哪些信息呢?这我们可以从一个api中得到,
GetTokenInformation https://msdn.microsoft.com/en-us/library/windows/desktop/aa446671(v=vs.85).aspx
想要获取的信息类别
TOKEN_INFORMATION_CLASS
typedef enum _TOKEN_INFORMATION_CLASS { TokenUser = 1, TokenGroups, TokenPrivileges, TokenOwner, TokenPrimaryGroup, TokenDefaultDacl, TokenSource, TokenType, TokenImpersonationLevel, TokenStatistics, TokenRestrictedSids, TokenSessionId, TokenGroupsAndPrivileges, TokenSessionReference, TokenSandBoxInert, TokenAuditPolicy, TokenOrigin, TokenElevationType, TokenLinkedToken, TokenElevation, TokenHasRestrictions, TokenAccessInformation, TokenVirtualizationAllowed, TokenVirtualizationEnabled, TokenIntegrityLevel, TokenUIAccess, TokenMandatoryPolicy, TokenLogonSid, TokenIsAppContainer, TokenCapabilities, TokenAppContainerSid, TokenAppContainerNumber, TokenUserClaimAttributes, TokenDeviceClaimAttributes, TokenRestrictedUserClaimAttributes, TokenRestrictedDeviceClaimAttributes, TokenDeviceGroups, TokenRestrictedDeviceGroups, TokenSecurityAttributes, TokenIsRestricted, MaxTokenInfoClass } TOKEN_INFORMATION_CLASS, *PTOKEN_INFORMATION_CLASS; |
如此在这里我们一一获取下这些信息
1.TOKEN_USER: https://msdn.microsoft.com/en-us/library/windows/desktop/aa379634(v=vs.85).aspx
![]() ![]() |
2.TOKEN_GROUPS: https://msdn.microsoft.com/en-us/library/windows/desktop/aa379624(v=vs.85).aspx
https://msdn.microsoft.com/en-us/library/windows/desktop/aa379630(v=vs.85).aspx
TOKEN_PRIVILEGE 跟USER RIGHTS还是有区别的
typedef struct _TOKEN_PRIVILEGES { DWORD PrivilegeCount; LUID_AND_ATTRIBUTES Privileges[ANYSIZE_ARRAY]; } TOKEN_PRIVILEGES, *PTOKEN_PRIVILEGES;
typedef struct _LUID_AND_ATTRIBUTES { LUID Luid; DWORD Attributes; } LUID_AND_ATTRIBUTES, *PLUID_AND_ATTRIBUTES;
(LUID) A 64-bit value that is guaranteed to be unique on the operating system that generated it until the system is restarted.
唯一标志windows某存在对象 "X" 的身份An LUID_AND_ATTRIBUTES structure can represent an LUID whose attributes change frequently,
LUID_AND_ATTRIBUTES结构体能代表 状态经常发生变化的LUID,而LUID也可以代表一个PRIVILEGE....
TOKEN_PRIVILEGES在内存中的形式
![]() ![]() |
Privilege 常量
https://msdn.microsoft.com/en-us/library/windows/desktop/bb530716(v=vs.85).aspx
TOKEN_OWNER https://msdn.microsoft.com/en-us/library/windows/desktop/aa379628(v=vs.85).aspx
The TOKEN_OWNER structure contains the default owner security identifier (SID) that will be applied to newly created objects.
上段说明TOKEN_OWNER 结构体包含了一个默认的SID,它被用于新创建的对象---? 内核对象 如EVENT,MUTANT,SEMAPHORE...?,有待校验
A pointer to a SID structure representing a user who will become the owner of any objects created by a process using this access token. The SID must be one of the user or group SIDs already in the token.
被这个token关联的进程所创建的对象,被该SID表示的"用户"拥有,这个"用户"可以是 个体用户或者组 ,前提使他们得出现在Token中
![]() 注意这个SID代表着的用户和Toke关联的用户不是同一个对象, ![]() |
TOKEN_PRIMARY_GROUP https://msdn.microsoft.com/en-us/library/windows/desktop/aa379629(v=vs.85).aspx
The TOKEN_PRIMARY_GROUP structure specifies a group security identifier (SID) for an access token.
该TOKEN_PRIMARY_GROUP 结构体指定了一个 组SID
A pointer to a SID structure representing a group that will become the primary group of any objects created by a process using this access token.
The SID must be one of the group SIDs already in the token.
代表着 组 的一个SID,这个组 将成为 拥有这个TOKEN的进程所创建an的 所有对象 的Primary group
![]() |
TOKEN_DEFAULT_DACL
A pointer to an ACL structure assigned by default to any objects created by the user. The user is represented by the access token.
一个指向ACL结构体的指针,该结构体在用户进程创建对象的时候被默认分配给该对象,暂时不分析这部分
TOKEN_SOURCE https://msdn.microsoft.com/en-us/library/windows/desktop/aa379631(v=vs.85).aspx
The TOKEN_SOURCE structure identifies the source of an access token
TOKEN_SOURCE 结构体说明了该token的来源
typedef struct _TOKEN_SOURCE { CHAR SourceName[TOKEN_SOURCE_LENGTH]; LUID SourceIdentifier; } TOKEN_SOURCE, *PTOKEN_SOURCE;SourceName
Specifies an 8-byte character string used to identify the source of an access token. This is used to distinguish between such sources as Session Manager, LAN Manager, and RPC Server. A string, rather than a constant, is used to identify the source so users and developers can make extensions to the system, such as by adding other networks, that act as the source of access tokens.
指定8字节长的字符串,用来表示TOken的来源,这可被用来却分诸如 Session Manager,LAN Manager,RPC Server等来源,用字符串而不是一个常量
表示,方便用户,对系统进行扩展,比如添加其他的 网络,用来作为Token的来源
SourceIdentifierSpecifies a locally unique identifier (LUID) provided by the source component named by the SourceName member. This value aids the source component in relating context blocks, such as session-control structures, to the token. This value is typically, but not necessarily, an LUID.
SourceName成员代表的来源组件 提供的本地唯一标识符....
![]() |
TOKEN_TYPE https://msdn.microsoft.com/en-us/library/windows/desktop/aa379633(v=vs.85).aspx
The TOKEN_TYPE enumeration contains values that differentiate between a primary token and an impersonation token.
![]() |
SECURITY_IMPERSONATION_LEVEL https://msdn.microsoft.com/en-us/library/windows/desktop/aa379572(v=vs.85).aspx
typedef enum _SECURITY_IMPERSONATION_LEVEL { SecurityAnonymous, SecurityIdentification, SecurityImpersonation, SecurityDelegation } SECURITY_IMPERSONATION_LEVEL, *PSECURITY_IMPERSONATION_LEVEL;目前用不着,忽略直接pass
If the access token is not an impersonation token, the function fails.
如果token不是impersionation token函数失败
TOKEN_SESSIONID
indicates the Terminal Services session identifier that is associated with the token.If the token is associated with the terminal server client session, the session identifier is nonzero.In a non-Terminal Services environment, the session identifier is zero.
If TokenSessionId is set with SetTokenInformation, the application must have the Act As Part Of the Operating System privilege, and the application must be enabled to set the session ID in a token.
上段文字说明,TOEKN_SEESIONID 指出 与该token相关的 终端服务会话Terminal Services session ,如果相关Session是 Terminal Server Client session,则session id非0
,在 非终端 服务的环境下,session id为0,
![]() |
其他就不一一列举了,很多东西,自己还没仔细看过,上述样本贴码如下
// TokenInformation.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include
#include
#include
VOID RetGroupDwordAttributesToStr(DWORD attributes,LPTSTR szAttributes )
{
UINT len = 0;
if(attributes & SE_GROUP_ENABLED)
len += wsprintf(szAttributes + len,TEXT("%s"),TEXT("SE_GROUP_ENABLED | "));
if(attributes & SE_GROUP_ENABLED_BY_DEFAULT)
len += wsprintf(szAttributes + len,TEXT("%s"),TEXT("SE_GROUP_ENABLED_BY_DEFAULT | "));
if(attributes & SE_GROUP_INTEGRITY)
len += wsprintf(szAttributes + len,TEXT("%s"),TEXT("SE_GROUP_INTEGRITY | "));
if(attributes & SE_GROUP_INTEGRITY_ENABLED)
len += wsprintf(szAttributes + len,TEXT("%s"),TEXT("SE_GROUP_INTEGRITY_ENABLED | "));
if(attributes & SE_GROUP_LOGON_ID)
len += wsprintf(szAttributes + len,TEXT("%s"),TEXT("SE_GROUP_LOGON_ID | "));
if(attributes & SE_GROUP_MANDATORY)
len += wsprintf(szAttributes + len,TEXT("%s"),TEXT("SE_GROUP_MANDATORY | "));
if(attributes & SE_GROUP_OWNER)
len += wsprintf(szAttributes + len,TEXT("%s"),TEXT("SE_GROUP_OWNER | "));
if(attributes & SE_GROUP_RESOURCE)
len += wsprintf(szAttributes + len,TEXT("%s"),TEXT("SE_GROUP_RESOURCE | "));
if(attributes & SE_GROUP_USE_FOR_DENY_ONLY)
len += wsprintf(szAttributes + len,TEXT("%s"),TEXT("SE_GROUP_USE_FOR_DENY_ONLY | "));
return;
}
VOID RetPrivDwordAttributesToStr(DWORD attributes,LPTSTR szAttrbutes)
{
UINT len = 0;
if(attributes & SE_PRIVILEGE_ENABLED)
len += wsprintf(szAttrbutes,TEXT(" SE_PRIVILEGE_ENABLED |"));
if(attributes & SE_PRIVILEGE_ENABLED_BY_DEFAULT)
len += wsprintf(szAttrbutes,TEXT(" SE_PRIVILEGE_ENABLED_BY_DEFAULT |"));
if(attributes & SE_PRIVILEGE_REMOVED)
len += wsprintf(szAttrbutes,TEXT(" SE_PRIVILEGE_REMOVED |"));
if(attributes & SE_PRIVILEGE_USED_FOR_ACCESS)
len += wsprintf(szAttrbutes,TEXT(" SE_PRIVILEGE_USED_FOR_ACCESS |"));
if(szAttrbutes[0] == 0)
wsprintf(szAttrbutes,TEXT(" SE_PRIVILEGE_DISABLED |"));
return ;
}
VOID PrintTokenInfoXX(HANDLE hToken,TOKEN_INFORMATION_CLASS tic )
{
setlocale(LC_ALL,"");
switch(tic)
{
case TokenUser:
{
//The TOKEN_USER structure identifies the user associated with an access token.
//TOKEN_USER 结构体 是用来标志和 Token相关联的用户
PVOID ptu = NULL;
DWORD dwRet = 0;
if(!GetTokenInformation(
hToken,
tic,
ptu,
dwRet,
&dwRet
))
{
DWORD error = GetLastError( );
if(error == ERROR_INSUFFICIENT_BUFFER)
{
ptu =(LPVOID) calloc(dwRet,1);
if(!GetTokenInformation(
hToken,
tic,
ptu,
dwRet,
&dwRet
))
{
MessageBox(0,TEXT("获取TokenUser信息失败"),0,0);
return ;
}
goto SUCCESS_TokenUser;
}
MessageBox(0,TEXT("获取TokenUser信息失败"),0,0);
return ;
}
SUCCESS_TokenUser:
LPTSTR lpszSID = NULL;
ConvertSidToStringSid( ((PTOKEN_USER)ptu)->User.Sid,&lpszSID );
_tprintf(TEXT("USER SID: %s\t"),lpszSID);
TCHAR name[MAX_PATH] = {0};
DWORD len1 = MAX_PATH;
DWORD len2 = MAX_PATH;
TCHAR domain[MAX_PATH] = {0};
SID_NAME_USE pnu;
LookupAccountSid(NULL,((PTOKEN_USER)ptu)->User.Sid,name,&len1,domain,&len2,&pnu);
_tprintf(TEXT("USER NAME: %s of domain %s\n"),name,domain);
LocalFree(lpszSID);
free(ptu);
_tprintf(TEXT("****************************************************************************************************\n"));
_tprintf(TEXT("****************************************************************************************************\n\n\n"));
}
break;
case TokenGroups:
{
PTOKEN_GROUPS ptg = NULL;
DWORD dwRet = 0;
if(!GetTokenInformation(hToken,
TokenGroups,
ptg,
dwRet,
&dwRet
))
{
DWORD error = GetLastError( );
if(error == ERROR_INSUFFICIENT_BUFFER)
{
ptg = (PTOKEN_GROUPS)calloc(dwRet,1);
if(!GetTokenInformation(hToken,
TokenGroups,
ptg,
dwRet,
&dwRet
))
{
MessageBox(0,TEXT("获取TokenGroups信息失败"),0,0);
return ;
}
goto SUCCESS_TokenGroups;
}
MessageBox(0,TEXT("获取TokenGroups信息失败"),0,0);
return ;
}
SUCCESS_TokenGroups:
for(int i = 0; i < ptg->GroupCount; i++)
{
LPTSTR lpszSID = NULL;
ConvertSidToStringSid((ptg->Groups+i)->Sid,&lpszSID);
_tprintf(TEXT("Group SID is %s\t"),lpszSID);
TCHAR name[MAX_PATH] = {0};
DWORD len1 = MAX_PATH;
DWORD len2 = MAX_PATH;
TCHAR domain[MAX_PATH] = {0};
SID_NAME_USE pnu;
LookupAccountSid(NULL,ptg->Groups[i].Sid,name,&len1,domain,&len2,&pnu);
_tprintf(TEXT("GROUP NAME: %s of domain %s"),name,domain);
TCHAR szAttributes[1024] = {0};
RetGroupDwordAttributesToStr((ptg->Groups + i)->Attributes,szAttributes);
_tprintf(TEXT("\n\t Attributes: %70s"),szAttributes);
_tprintf(TEXT("\n----------------------------------------------------------------------------------------\n"));
LocalFree(lpszSID);
}
free(ptg);
_tprintf(TEXT("****************************************************************************************************\n"));
_tprintf(TEXT("****************************************************************************************************\n\n\n"));
}
break;
case TokenPrivileges:
{
PTOKEN_PRIVILEGES ppriv = NULL;
DWORD dwRet = 0;
if(!GetTokenInformation(hToken,
TokenGroups,
ppriv,
dwRet,
&dwRet
))
{
DWORD error = GetLastError( );
if(error == ERROR_INSUFFICIENT_BUFFER)
{
ppriv = (PTOKEN_PRIVILEGES)calloc(dwRet,1);
if(!GetTokenInformation(hToken,
TokenPrivileges,
ppriv,
dwRet,
&dwRet
))
{
MessageBox(0,TEXT("获取TokenPrivilege信息失败"),0,0);
return ;
}
goto SUCCESS_TokenPrivilege;
}
MessageBox(0,TEXT("获取TokenPrivilege信息失败"),0,0);
return ;
}
SUCCESS_TokenPrivilege:
for(int i = 0; i < ppriv->PrivilegeCount; i++)
{
TCHAR lpszPriv[MAX_PATH] = {0};
DWORD dwRet = MAX_PATH;
BOOL n=LookupPrivilegeName(
NULL,
&(ppriv->Privileges[i].Luid),
lpszPriv,
&dwRet
);
_tprintf(TEXT("[%d:]\t%s"),i,lpszPriv);
TCHAR lpszAttrbutes[1024] = {0};
RetPrivDwordAttributesToStr(ppriv->Privileges[i].Attributes,lpszAttrbutes);
_tprintf(TEXT("\n\t %s\n\n"),lpszAttrbutes);
}
free(ppriv);
_tprintf(TEXT("****************************************************************************************************\n"));
_tprintf(TEXT("****************************************************************************************************\n\n\n"));
}
break;
case TokenOwner:
{
PTOKEN_OWNER ptOwner = NULL;
DWORD dwRet = 0;
if(!GetTokenInformation(hToken,
TokenOwner,
ptOwner,
dwRet,
&dwRet
))
{
DWORD error = GetLastError( );
if(error == ERROR_INSUFFICIENT_BUFFER)
{
ptOwner = (PTOKEN_OWNER)calloc(dwRet,1);
if(!GetTokenInformation(hToken,
TokenOwner,
ptOwner,
dwRet,
&dwRet
))
{
MessageBox(0,TEXT("获取TokenOwner信息失败"),0,0);
return ;
}
goto SUCCESS_TokenOwner;
}
MessageBox(0,TEXT("获取TokenOwner信息失败"),0,0);
return ;
}
SUCCESS_TokenOwner:;
LPTSTR lpszSID = NULL;
ConvertSidToStringSid(ptOwner->Owner,&lpszSID);
_tprintf(TEXT("OWNER SID: %s\t"),lpszSID);
TCHAR name[MAX_PATH] = {0};
DWORD len1 = MAX_PATH;
DWORD len2 = MAX_PATH;
TCHAR domain[MAX_PATH] = {0};
SID_NAME_USE pnu;
LookupAccountSid(NULL,ptOwner->Owner,name,&len1,domain,&len2,&pnu);
_tprintf(TEXT("OWNER NAME: %s of domain %s\n"),name,domain);
LocalFree(lpszSID);
free(ptOwner);
_tprintf(TEXT("****************************************************************************************************\n"));
_tprintf(TEXT("****************************************************************************************************\n\n\n"));
}
break;
case TokenPrimaryGroup:
{
PTOKEN_PRIMARY_GROUP ppg = NULL;
DWORD dwRet = 0;
if(!GetTokenInformation(hToken,
TokenPrimaryGroup,
ppg,
dwRet,
&dwRet
))
{
DWORD error = GetLastError( );
if(error == ERROR_INSUFFICIENT_BUFFER)
{
ppg = (PTOKEN_PRIMARY_GROUP)calloc(dwRet,1);
if(!GetTokenInformation(hToken,
TokenPrimaryGroup,
ppg,
dwRet,
&dwRet
))
{
MessageBox(0,TEXT("获取TokenPrimaryGroup信息失败"),0,0);
return ;
}
goto SUCCESS_TokenPrimaryGroup;
}
MessageBox(0,TEXT("获取TokenPrimaryGroup信息失败"),0,0);
return ;
}
SUCCESS_TokenPrimaryGroup:;
LPTSTR lpszSID = NULL;
ConvertSidToStringSid(ppg->PrimaryGroup,&lpszSID);
_tprintf(TEXT("PRIMARY GROUP SID: %s\t"),lpszSID);
TCHAR name[MAX_PATH] = {0};
DWORD len1 = MAX_PATH;
DWORD len2 = MAX_PATH;
TCHAR domain[MAX_PATH] = {0};
SID_NAME_USE pnu;
LookupAccountSid(NULL,ppg->PrimaryGroup,name,&len1,domain,&len2,&pnu);
_tprintf(TEXT("GROUP NAME: %s of domain %s\n"),name,domain);
LocalFree(lpszSID);
free(ppg);
_tprintf(TEXT("****************************************************************************************************\n"));
_tprintf(TEXT("****************************************************************************************************\n\n\n"));
}
break;
case TokenDefaultDacl:
break;
case TokenSource:
{
PTOKEN_SOURCE pts = NULL;
DWORD dwRet = 0;
if(!GetTokenInformation(hToken,
TokenSource,
pts,
dwRet,
&dwRet
))
{
DWORD error = GetLastError( );
if(error == ERROR_INSUFFICIENT_BUFFER)
{
pts = (PTOKEN_SOURCE)calloc(dwRet,1);
if(!GetTokenInformation(hToken,
TokenSource,
pts,
dwRet,
&dwRet
))
{
MessageBox(0,TEXT("获取TokenSource信息失败"),0,0);
return ;
}
goto SUCCESS_TokenSource;
}
MessageBox(0,TEXT("获取TokenSource信息失败"),0,0);
return ;
}
SUCCESS_TokenSource:;
printf("Token Source NAME: %s\n",pts->SourceName);
free(pts);
_tprintf(TEXT("****************************************************************************************************\n"));
_tprintf(TEXT("****************************************************************************************************\n\n\n"));
}
break;
case TokenType:
{
PTOKEN_TYPE ptt = NULL;
DWORD dwRet = 0;
if(!GetTokenInformation(hToken,
TokenType,
ptt,
dwRet,
&dwRet
))
{
DWORD error = GetLastError( );
if(error == ERROR_INSUFFICIENT_BUFFER)
{
ptt = (PTOKEN_TYPE)calloc(dwRet,1);
if(!GetTokenInformation(hToken,
TokenType,
ptt,
dwRet,
&dwRet
))
{
MessageBox(0,TEXT("获取TokenType信息失败"),0,0);
return ;
}
goto SUCCESS_TokenType;
}
MessageBox(0,TEXT("获取TokenType信息失败"),0,0);
return ;
}
SUCCESS_TokenType:
_tprintf(TEXT("Token Type: %s\n"),(*ptt) == TokenPrimary?TEXT("TokenPrimary"):TEXT("TokenImpersonation"));
free(ptt);
_tprintf(TEXT("****************************************************************************************************\n"));
_tprintf(TEXT("****************************************************************************************************\n\n\n"));
}
break;
case TokenImpersonationLevel:
{
PSECURITY_IMPERSONATION_LEVEL psil = NULL;
DWORD dwRet = 0;
if(!GetTokenInformation(hToken,
TokenImpersonationLevel,
psil,
dwRet,
&dwRet
))
{
DWORD error = GetLastError( );
if(error == ERROR_INSUFFICIENT_BUFFER)
{
psil = (PSECURITY_IMPERSONATION_LEVEL)calloc(dwRet,1);
if(!GetTokenInformation(hToken,
TokenImpersonationLevel,
psil,
dwRet,
&dwRet
))
{
MessageBox(0,TEXT("获取TokenImpersonationLevel信息失败"),0,0);
return ;
}
goto SUCCESS_TokenImpersonationLevel;
}
MessageBox(0,TEXT("获取TokenImpersonationLevel信息失败,可能原因: 该Token不是Impersonation Token"),0,0);
return ;
}
SUCCESS_TokenImpersonationLevel:
if((*psil) == SecurityAnonymous)
_tprintf(TEXT("TokenImpersonationLevel : %s"),TEXT("SecurityAnonymous"));
else if((*psil) == SecurityIdentification)
_tprintf(TEXT("TokenImpersonationLevel : %s"),TEXT("SecurityIdentification"));
else if((*psil) == SecurityImpersonation)
_tprintf(TEXT("TokenImpersonationLevel : %s"),TEXT("SecurityImpersonation"));
else
_tprintf(TEXT("TokenImpersonationLevel : %s"),TEXT("SecurityDelegation"));
free(psil);
_tprintf(TEXT("****************************************************************************************************\n"));
_tprintf(TEXT("****************************************************************************************************\n\n\n"));
}
break;
case TokenStatistics:
break;
case TokenRestrictedSids:
break;
case TokenSessionId:
{
DWORD dwSessionID = 0;
DWORD dwRet = sizeof(dwSessionID);
if(!GetTokenInformation(hToken,
TokenSessionId,
&dwSessionID,
dwRet,
&dwRet
))
{
MessageBox(0,TEXT("获取TokenSessionId信息失败"),0,0);
return ;
}
_tprintf(TEXT("Session ID is %08X\n"),dwSessionID);
_tprintf(TEXT("****************************************************************************************************\n"));
_tprintf(TEXT("****************************************************************************************************\n\n\n"));
}
break;
case TokenGroupsAndPrivileges:
break;
case TokenSandBoxInert:
break;
case TokenOrigin:
break;
case TokenElevationType:
break;
case TokenLinkedToken:
break;
case TokenElevation:
break;
case TokenHasRestrictions:
break;
case TokenAccessInformation:
break;
case TokenVirtualizationAllowed:
break;
case TokenVirtualizationEnabled:
break;
case TokenIntegrityLevel:
break;
case TokenUIAccess:
break;
case TokenMandatoryPolicy:
break;
case TokenLogonSid:
break;
case TokenCapabilities:
break;
case TokenUserClaimAttributes:
break;
case TokenDeviceClaimAttributes:
break;
case TokenDeviceGroups:
break;
case TokenRestrictedDeviceGroups:
break;
}
}
int _tmain(int argc, _TCHAR* argv[])
{
HANDLE hToken = NULL;
if(!OpenProcessToken(GetCurrentProcess( ),TOKEN_ALL_ACCESS,&hToken))
{
MessageBox(0,TEXT("Token获取失败"),0,0);
return 0;
}
TOKEN_INFORMATION_CLASS tic[31] = {
TokenUser,
TokenGroups,
TokenPrivileges,
TokenOwner,
TokenPrimaryGroup,
TokenDefaultDacl,
TokenSource,
TokenType,
TokenImpersonationLevel,
TokenStatistics,
TokenRestrictedSids,
TokenSessionId,
TokenGroupsAndPrivileges,
TokenSandBoxInert,
TokenOrigin,
TokenElevationType,
TokenLinkedToken,
TokenElevation,
TokenHasRestrictions,
TokenAccessInformation,
TokenVirtualizationAllowed,
TokenVirtualizationEnabled,
TokenIntegrityLevel,
TokenUIAccess,
TokenMandatoryPolicy,
TokenLogonSid,
TokenCapabilities,
TokenUserClaimAttributes,
TokenDeviceClaimAttributes,
TokenDeviceGroups,
TokenRestrictedDeviceGroups
};
const int total = 31;
for(int i = 0; i < total; i++)
PrintTokenInfoXX(hToken,tic[i]);
return 0;
}