SepCreateTokenEx
NTSTATUS __stdcall SepCreateTokenEx(
VOID **TokenHandle,
INT8 RequestorMode,
UINT64 DesiredAccess,
_OBJECT_ATTRIBUTES *ObjectAttributes,
_TOKEN_TYPE TokenType,
_SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
_LUID *AuthenticationId,
_LARGE_INTEGER *ExpirationTime,
_SID_AND_ATTRIBUTES *User,
UINT64 GroupCount,
_SID_AND_ATTRIBUTES *Groups,
UINT64 GroupsLength,
UINT64 PrivilegeCount,
_LUID_AND_ATTRIBUTES *Privileges,
VOID *Owner,
VOID *PrimaryGroup,
_ACL *DefaultDacl,
_TOKEN_SOURCE *TokenSource,
_TOKEN_SECURITY_ATTRIBUTES_INFORMATION *UserClaims,
_TOKEN_SECURITY_ATTRIBUTES_INFORMATION *DeviceClaims,
UINT64 DeviceGroupsCount,
_SID_AND_ATTRIBUTES *DeviceGroups,
_TOKEN_MANDATORY_POLICY *MandatoryPolicy,
UINT8 SystemToken){
void *v26;
unsigned int v27;
int v28;
NTSTATUS result;
void *Sid;
unsigned int v31;
unsigned int v32;
__int64 v33;
_SID_AND_ATTRIBUTES *v34;
UINT8 v35;
__int64 v36;
bool v37;
int v38;
char v39;
unsigned int Attributes;
int v41;
unsigned int *p_Attributes;
unsigned int v43;
unsigned __int8 *v44;
_SID_IDENTIFIER_AUTHORITY *v45;
char v46;
__int64 v47;
int v48;
__int64 v49;
__int64 v50;
__int64 v51;
VOID **PoolWithTag;
VOID **v53;
_QWORD *v54;
VOID **v55;
_ERESOURCE *v56;
int v57;
unsigned __int8 *v58;
unsigned int v59;
unsigned int v60;
int v61;
int Object;
_TOKEN *v63;
_TOKEN *v64;
_LUID *v65;
__int64 v66;
__int64 v67;
_SEP_TOKEN_DIAG_TRACK_ENTRY *v68;
_SEP_TOKEN_DIAG_TRACK_ENTRY **p_DiagnosticInfo;
_LUID *v70;
int v71;
_SID_AND_ATTRIBUTES *v72;
unsigned int v73;
__int64 v74;
VOID **v75;
unsigned __int8 *v76;
unsigned int v77;
unsigned __int16 *v78;
char *v79;
_TOKEN *v80;
int v81;
int v82;
unsigned int v83;
UINT8 v84;
UINT8 v85;
VOID *v86;
unsigned int *v87;
unsigned int v88;
unsigned __int64 v89;
UINT8 v90;
_TOKEN *v91;
VOID **v92;
_SEP_TOKEN_DIAG_TRACK_ENTRY *v93;
_EPROCESS *Process;
unsigned int v95;
__int64 Count;
VOID *ParseContext;
UINT64 ObjectBodySize;
UINT64 PagedPoolCharge;
UINT64 NonPagedPoolCharge;
char v101;
UINT8 SecurityDescriptorPresent;
char v103;
INT8 ProbeMode;
int v105;
UINT64 RemainingTargetSidBufferSize;
_LUID_AND_ATTRIBUTES *p_DefaultDacl;
int v108;
int v109;
_TOKEN *Token;
UINT64 v111;
_SID_AND_ATTRIBUTES *Source;
PVOID v113;
PVOID P;
VOID *NextTargetSid;
PVOID Sid1;
int v117;
_DWORD DesiredAccessa[3];
_SID_AND_ATTRIBUTES *v119;
PVOID *Handle;
_OBJECT_ATTRIBUTES *ObjectAttributesa;
__int64 v122;
__int64 v123;
__int64 v124;
_LUID *LogonId;
VOID *Src;
_SID_AND_ATTRIBUTES *v127;
_TOKEN_SECURITY_ATTRIBUTES_INFORMATION *v128;
_TOKEN_SECURITY_ATTRIBUTES_INFORMATION *v129;
char v130[160];
_AUX_ACCESS_DATA AuxData;
v26 = Owner;
v27 = GroupCount;
v109 = -1;
LogonId = AuthenticationId;
p_DefaultDacl = Privileges;
Sid1 = PrimaryGroup;
Src = DefaultDacl;
v129 = UserClaims;
v128 = DeviceClaims;
v127 = DeviceGroups;
DesiredAccessa[0] = DesiredAccess;
v28 = 0;
ProbeMode = RequestorMode;
Handle = TokenHandle;
Token = 0i64;
NextTargetSid = 0i64;
v105 = 0;
ObjectAttributesa = ObjectAttributes;
Source = User;
v119 = Groups;
v113 = Owner;
memset(v130, 0i64, sizeof(v130));
memset(&AuxData, 0i64, sizeof(AuxData));
*(_QWORD *)&DesiredAccessa[1] = 0i64;
v101 = 0;
v103 = 0;
SecurityDescriptorPresent = 0;
P = 0i64;
result = SeCaptureObjectAttributeSecurityDescriptorPresent(
ObjectAttributes,
RequestorMode,
&SecurityDescriptorPresent);
if( result >= 0 )
{
Sid = User->Sid;
v31 = 0;
if( (_DWORD)GroupCount )
{
do
{
v32 = v31;
while( v32 < v27 )
{
if( !RtlEqualSid(Sid, Groups[v32].Sid) || (Groups[v32].Attributes & 0x20) != 0 )
++v32;
else
Groups[v32] = Groups[--v27];
}
v33 = v31++;
Sid = Groups[v33].Sid;
}
while( v31 < v27 );
v34 = Source;
v26 = v113;
Sid = Source->Sid;
}
else
{
v34 = Source;
}
v35 = RtlEqualSid(Sid1, Sid);
v36 = 0i64;
v37 = v35 != 0;
if( v26 )
{
v90 = RtlEqualSid(v26, Sid);
v36 = 0i64;
v39 = 0;
LOBYTE(v38) = 1;
if( v90 )
v39 = 1;
}
else
{
LOBYTE(v38) = 1;
v39 = 1;
}
Attributes = v34->Attributes;
if( (Attributes & 0x10) != 0 )
{
if( (Attributes & 6) != 0 )
return -1073741811;
v28 = 2048;
v105 = 2048;
}
v108 = 0;
if( v27 )
{
v41 = 1;
p_Attributes = &v119->Attributes;
v108 = 0;
while( 1 )
{
v43 = *p_Attributes;
if( ((unsigned __int8)*p_Attributes & (unsigned __int8)v38) != 0 )
{
v43 |= 6u;
*p_Attributes = v43;
}
if( (v43 & 0x10) != 0 )
{
if( (v43 & 6) != 0 )
return -1073741811;
v28 |= 0x800u;
v105 = v28;
}
v44 = (unsigned __int8 *)*((_QWORD *)p_Attributes - 1);
RtlIdentifierAuthoritySid(v44);
v45 = RtlIdentifierAuthoritySid(SeUntrustedMandatorySid);
v48 = *(_DWORD *)v45->Value - *(_DWORD *)v47;
if( *(_DWORD *)v45->Value == *(_DWORD *)v47 )
v48 = *(unsigned __int16 *)&v45->Value[4] - *(unsigned __int16 *)(v47 + 4);
if( !v48 )
{
v81 = v44[1];
if( (_BYTE)v81 )
{
v82 = v44[1];
if( *(_DWORD *)&v44[4 * (v81 - 1) + 8] > 0x4000u )
return -1073740730;
}
else
{
v82 = v36;
}
if( (v46 & 0x40) != 0 )
break;
}
LABEL_20:
if( !v37 )
{
v84 = RtlEqualSid(Sid1, v44);
v36 = 0i64;
v38 = 1;
if( v84 )
v37 = 1;
}
if( !v39 )
{
v85 = RtlEqualSid(v113, v44);
v36 = 0i64;
if( v85 )
{
if( (*p_Attributes & 8) == 0 )
return -1073741734;
v38 = 1;
v108 = v41;
v39 = 1;
}
else
{
v38 = 1;
}
}
v41 += v38;
p_Attributes += 4;
if( v41 - 1 >= v27 )
goto LABEL_23;
}
if( v109 != -1 )
return -1073741811;
v109 = v41;
if( (_BYTE)v81 )
{
v83 = *(_DWORD *)&v44[4 * (v82 - 1) + 8];
if( v83 >= 0x3000 )
{
v101 = v38;
v28 |= 0x2000u;
LABEL_73:
v105 = v28;
goto LABEL_20;
}
if( v83 >= 0x2000 )
{
LABEL_71:
v101 = v36;
if( v83 >= 0x2000 )
v28 |= 0x2000u;
goto LABEL_73;
}
}
else
{
v83 = v36;
}
v103 = v38;
goto LABEL_71;
}
LABEL_23:
if( !v37 )
return -1073741733;
if( !v39 )
return -1073741734;
v49 = v36;
v122 = v36;
v50 = v36;
v123 = v36;
v51 = v36;
v124 = v36;
if( (_DWORD)PrivilegeCount )
{
v87 = &p_DefaultDacl->Attributes;
do
{
v88 = *v87;
if( (*v87 & 0x7FFFFFF8) != 0 )
return -1073741811;
v89 = *(v87 - 2);
*v87 &= 3u;
if( (unsigned int)v89 > 0x24 )
return -1073741728;
if( _bittest64(&v49, v89) )
return -1073741402;
v49 |= 1i64 << v89;
v122 = v49;
if( (v88 & 2) != 0 )
{
_bittestandset64(&v50, (unsigned int)v89);
v123 = v50;
}
if( (v88 & 1) != 0 )
{
_bittestandset64(&v51, (unsigned int)v89);
v124 = v51;
}
LODWORD(v36) = v36 + 1;
v87 += 3;
}
while( (unsigned int)v36 < (unsigned int)PrivilegeCount );
}
if( MandatoryPolicy && (MandatoryPolicy->Policy & 0xFFFFFFFC) != 0 )
return -1073741811;
PoolWithTag = ExAllocatePoolWithTag(1ui64, 0x30ui64, 1950442835i64);
v53 = PoolWithTag;
if( !PoolWithTag )
return -1073741670;
*(_DWORD *)PoolWithTag = 0;
v54 = PoolWithTag + 1;
*((_DWORD *)v53 + 6) = 0;
v54[1] = v54;
*v54 = v54;
v53[5] = v53 + 4;
v53[4] = v53 + 4;
if( SeTokenLeakTracking )
{
P = ExAllocatePoolWithTag(1ui64, 0x120ui64, 1950442835i64);
v55 = (VOID **)P;
if( !P )
{
v92 = v53;
goto LABEL_123;
}
}
else
{
v55 = 0i64;
}
*(_QWORD *)&DesiredAccessa[1] = ExpLuidIncrement + _InterlockedExchangeAdd64(&ExpLuid, ExpLuidIncrement);
v56 = (_ERESOURCE *)ExAllocatePoolWithTag(0x200ui64, 0x68ui64, 1817470291i64);
if( v56 )
{
v57 = 16 * v27;
LODWORD(v113) = 16 * v27;
if( SepTokenSidSharingEnabled )
{
v59 = (v57 + 23) & 0xFFFFFFF8;
LODWORD(v111) = GroupsLength;
}
else
{
v58 = (unsigned __int8 *)Source->Sid;
LODWORD(v111) = (GroupsLength + 7) & 0xFFFFFFF8;
v59 = v57 + ((RtlLengthRequiredSid(v58[1]) + 3) & 0xFFFFFFFC) + v111 + 16;
}
LODWORD(RemainingTargetSidBufferSize) = v59;
v60 = (RtlLengthRequiredSid(*((unsigned __int8 *)Sid1 + 1)) + 3) & 0xFFFFFFFC;
if( Src )
v60 += (*((unsigned __int16 *)Src + 1) + 3) & 0xFFFFFFFC;
v61 = 4096;
if( v60 >= 0x1000 )
v61 = v60;
LODWORD(NonPagedPoolCharge) = 0;
v117 = v61;
LODWORD(PagedPoolCharge) = v59 + 1168 + v61;
LODWORD(ObjectBodySize) = v59 + 1168;
Object = ObCreateObject(
ProbeMode,
(_OBJECT_TYPE *)SeTokenObjectType,
ObjectAttributesa,
1,
0i64,
ObjectBodySize,
PagedPoolCharge,
NonPagedPoolCharge,
(VOID **)&Token);
if( Object < 0 )
{
ExFreePoolWithTag(v53, 0);
if( SeTokenLeakTracking )
ExFreePoolWithTag(P, 0);
ExFreePoolWithTag(v56, 0);
return Object;
}
v63 = Token;
Token->TokenLock = v56;
ExInitializeResourceLite((INT64)v56);
v64 = Token;
v63->TokenId = (_LUID)(ExpLuidIncrement + _InterlockedExchangeAdd64(&ExpLuid, ExpLuidIncrement));
v64->ParentTokenId = 0i64;
v65 = LogonId;
v64->OriginatingLogonSession = 0i64;
p_DefaultDacl = 0i64;
v64->AuthenticationId = *v65;
v66 = *(_QWORD *)&DesiredAccessa[1];
v64->TokenInUse = 0;
v64->ModifiedId = (_LUID)v66;
v64->ExpirationTime = *ExpirationTime;
v64->TokenType = TokenType;
v64->ImpersonationLevel = ImpersonationLevel;
LODWORD(v66) = v105;
v64->TokenSource = *TokenSource;
v64->TokenFlags = v66;
LODWORD(v66) = v117;
v64->SessionId = 0;
v64->SessionObject = 0i64;
v64->DynamicCharged = v66;
LODWORD(v66) = v108;
v64->DynamicAvailable = 0;
v64->DefaultOwnerIndex = v66;
v64->DefaultDacl = 0i64;
v64->IntegrityLevelSidValue = 0i64;
v64->TokenSidValues = 0i64;
v64->VariableLength = v59;
p_DefaultDacl = (_LUID_AND_ATTRIBUTES *)&v64->DefaultDacl;
v64->IntegrityLevelIndex = v109;
v67 = v122;
v64->MandatoryPolicy = 0;
v64->Privileges.Present = v67;
v64->Privileges.Enabled = v123;
v64->Privileges.EnabledByDefault = v124;
v64->CapabilityCount = 0;
v64->Capabilities = 0i64;
v64->Package = 0i64;
v64->LowboxNumberEntry = 0i64;
v64->LowboxHandlesEntry = 0i64;
v64->BnoIsolationHandlesEntry = 0i64;
memset(&v64->CapabilitiesHash, 0i64, sizeof(v64->CapabilitiesHash));
v68 = (_SEP_TOKEN_DIAG_TRACK_ENTRY *)P;
p_DiagnosticInfo = &v64->DiagnosticInfo;
v64->TrustLevelSid = 0i64;
v64->TrustLinkedToken = 0i64;
v64->IndexEntry = 0i64;
v64->DiagnosticInfo = v68;
if( MandatoryPolicy )
v64->MandatoryPolicy = MandatoryPolicy->Policy;
if( !v101 )
{
v64->Privileges.Enabled &= 0xFFFFFFEEDFE9F97Bui64;
v64->Privileges.EnabledByDefault &= 0xFFFFFFEEDFE9F97Bui64;
}
if( v103 == 1 )
{
v64->Privileges.Enabled &= 0x202800000ui64;
v64->Privileges.EnabledByDefault &= 0x202800000ui64;
}
v70 = LogonId;
*(_OWORD *)v64->AuditPolicy.AdtTokenPolicy.PerUserPolicy = 0i64;
*(_QWORD *)&v64->AuditPolicy.AdtTokenPolicy.PerUserPolicy[16] = 0i64;
*(_DWORD *)&v64->AuditPolicy.AdtTokenPolicy.PerUserPolicy[24] = 0;
*(_WORD *)&v64->AuditPolicy.AdtTokenPolicy.PerUserPolicy[28] = 0;
v64->AuditPolicy.PolicySetStatus = 0;
v64->pSecurityAttributes = (_AUTHZBASEP_SECURITY_ATTRIBUTES_INFORMATION *)v53;
v64->pClaimAttributes = 0i64;
v64->DynamicPart = 0i64;
ObjectAttributesa = (_OBJECT_ATTRIBUTES *)&v64->DynamicPart;
v71 = SepReferenceLogonSession(v70, &v64->LogonSession);
if( v71 < 0 )
{
v64->TokenFlags |= 0x20u;
v64->LogonSession = 0i64;
ObfDereferenceObjectWithTag(v64, 0x746C6644ui64);
return v71;
}
if( SeTokenLeakTracking )
{
(*p_DiagnosticInfo)->ProcessCid = (void *)KeGetCurrentThread()[1].CycleTime;
(*p_DiagnosticInfo)->ThreadCid = *(void **)&KeGetCurrentThread()[1].CurrentRunTime;
(*p_DiagnosticInfo)->CreateMethod = 12;
(*p_DiagnosticInfo)->Count = 0;
(*p_DiagnosticInfo)->CaptureCount = 0;
v93 = *p_DiagnosticInfo;
Process = KeGetCurrentThread()->ApcState.Process;
*(_QWORD *)v93->ImageFileName = *(_QWORD *)Process->ImageFileName;
*(_DWORD *)&v93->ImageFileName[8] = *(_DWORD *)&Process->ImageFileName[8];
*(_WORD *)&v93->ImageFileName[12] = *(_WORD *)&Process->ImageFileName[12];
v93->ImageFileName[14] = Process->ImageFileName[14];
v95 = RtlWalkFrameChain((INT64)(*p_DiagnosticInfo)->CreateTrace, 30i64, 0i64);
if( KeGetCurrentIrql() < 2u )
RtlWalkFrameChain((INT64)&(*p_DiagnosticInfo)->CreateTrace[v95], 30 - v95, 1ui64);
v64 = Token;
SepAddTokenLogonSession(Token);
}
v72 = Source;
if( SepTokenSidSharingEnabled )
{
LODWORD(ParseContext) = v111;
Object = SepSetTokenUserAndGroups(v64, Source, v27, v119, (UINT64)ParseContext);
if( Object < 0 )
goto LABEL_59;
}
else
{
v73 = v59 - (_DWORD)v113;
v64->UserAndGroups = (_SID_AND_ATTRIBUTES *)&v64->VariablePart;
v74 = v27 + 1;
v64->UserAndGroupCount = v74;
NextTargetSid = &v64->VariablePart + 2 * v74;
LODWORD(RemainingTargetSidBufferSize) = v73 - 16;
RtlCopySidAndAttributesArray(
1ui64,
v72,
v73 - 16,
(_SID_AND_ATTRIBUTES *)&v64->VariablePart,
NextTargetSid,
&NextTargetSid,
&RemainingTargetSidBufferSize);
RtlCopySidAndAttributesArray(
v27,
v119,
(unsigned int)RemainingTargetSidBufferSize,
(_SID_AND_ATTRIBUTES *)&v64[1].TokenSource.SourceIdentifier,
NextTargetSid,
&NextTargetSid,
&RemainingTargetSidBufferSize);
}
RtlSidHashInitialize(v64->UserAndGroups, v64->UserAndGroupCount, &v64->SidHash);
v64->RestrictedSids = 0i64;
v64->RestrictedSidCount = 0;
v75 = ExAllocatePoolWithTag(1ui64, v60, 1683252563i64);
*(_QWORD *)&ObjectAttributesa->Length = v75;
if( v75 )
{
v76 = (unsigned __int8 *)Sid1;
v64->PrimaryGroup = v75;
v77 = RtlLengthRequiredSid(v76[1]);
RtlCopySid(v77, v75, v76);
v78 = (unsigned __int16 *)Src;
v79 = (char *)v75 + ((v77 + 3) & 0xFFFFFFFC);
if( Src )
{
v86 = Src;
p_DefaultDacl->Luid = (_LUID)v79;
memmove(v79, v86, v78[1]);
}
Object = SepSetTokenClaims(v64, v129, v128, (unsigned int)DeviceGroupsCount, v127);
if( Object >= 0 )
{
if( !SystemToken || (Object = SepSetTokenTrust(v64, SeProcTrustWinTcbSid), Object >= 0) )
{
if( SeTokenLeakTracking && SepTokenLeakMethodWatch == 12 )
{
if( KeGetCurrentThread()->ApcState.Process->UniqueProcessId == (void *)SepTokenLeakProcessCid )
{
(*p_DiagnosticInfo)->Count = _InterlockedIncrement(&SepTokenLeakMethodCount);
Count = (unsigned int)(*p_DiagnosticInfo)->Count;
if( (int)Count >= SepTokenLeakBreakCount )
{
DbgPrint("\nToken number 0x%x = 0x%p\n", Count, Token);
__debugbreak();
}
}
v64 = Token;
}
if( SystemToken )
{
v91 = Token;
if( KeGetCurrentThread()->ApcState.Process->Token.Value )
Object = ObInsertObject(Token, 0i64, 0, 0i64, 0i64, 0i64);
if( Object < 0 )
{
*Handle = 0i64;
}
else
{
if( !SecurityDescriptorPresent )
SepAppendAdminAceToTokenAcl(v91);
*Handle = v91;
}
return Object;
}
Object = SeCreateAccessState(
(_ACCESS_STATE *)v130,
&AuxData,
DesiredAccessa[0],
(_GENERIC_MAPPING *)((char *)SeTokenObjectType + 76));
v80 = v64;
if( Object < 0 )
goto LABEL_60;
Object = ObInsertObject(v64, (PACCESS_STATE)v130, 0, 1ui64, 0i64, Handle);
SeDeleteAccessState((_ACCESS_STATE *)v130);
if( Object < 0 )
return Object;
if( !SecurityDescriptorPresent )
SepAppendAdminAceToTokenAcl(v64);
}
}
}
else
{
Object = -1073741801;
}
LABEL_59:
v80 = v64;
LABEL_60:
ObfDereferenceObjectWithTag(v80, 0x746C6644ui64);
return Object;
}
ExFreePoolWithTag(v53, 0);
if( !SeTokenLeakTracking )
return -1073741670;
v92 = v55;
LABEL_123:
ExFreePoolWithTag(v92, 0);
return -1073741670;
}
return result;
}Referenced by:
NtCreateTokenEx
SepCreateToken