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