SepDuplicateToken

NTSTATUS __stdcall SepDuplicateToken(
        _TOKEN *ExistingToken,
        _OBJECT_ATTRIBUTES *ObjectAttributes,
        UINT8 EffectiveOnly,
        _TOKEN_TYPE TokenType,
        _SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
        INT8 RequestorMode,
        UINT8 SkipNonInheritableSecurityAttributes,
        _TOKEN **DuplicateToken){
  _SECURITY_IMPERSONATION_LEVEL v8; 
  VOID **v11; 
  VOID **PoolWithTag; 
  VOID **v14; 
  _QWORD *v15; 
  VOID **v16; 
  VOID **v17; 
  int Object; 
  _TOKEN *v19; 
  unsigned int v20; 
  _ETHREAD *CurrentThread; 
  _TOKEN *v22; 
  unsigned int v23; 
  unsigned int SessionId; 
  _ADAPTER_OBJECT *SessionObject; 
  __int128 v26; 
  _SEP_LUID_TO_INDEX_MAP_ENTRY **p_IndexEntry; 
  bool v28; 
  _SEP_LOGON_SESSION_REFERENCES *LogonSession; 
  int v30; 
  _SEP_LUID_TO_INDEX_MAP_ENTRY *IndexEntry; 
  _AUTHZBASEP_SECURITY_ATTRIBUTES_INFORMATION *pSecurityAttributes; 
  _SID_AND_ATTRIBUTES **p_UserAndGroups; 
  signed __int64 v34; 
  _SID_AND_ATTRIBUTES *v35; 
  unsigned int i; 
  _SID_AND_ATTRIBUTES *RestrictedSids; 
  _SID_AND_ATTRIBUTES *v38; 
  unsigned int j; 
  _ACL *DefaultDacl; 
  unsigned int v41; 
  size_t v42; 
  VOID **v43; 
  _ACL *v44; 
  signed __int64 v45; 
  UINT64 CapabilityCount; 
  void *Package; 
  _SEP_LOWBOX_NUMBER_ENTRY *LowboxNumberEntry; 
  _SEP_CACHED_HANDLES_ENTRY *LowboxHandlesEntry; 
  _SEP_CACHED_HANDLES_ENTRY *BnoIsolationHandlesEntry; 
  void *TrustLevelSid; 
  VOID *v52; 
  PVOID *v53; 
  _SEP_TOKEN_DIAG_TRACK_ENTRY *DiagnosticInfo; 
  _EPROCESS *Process; 
  __int64 Count; 
  VOID *v57; 
  UINT64 ObjectBodySize; 
  UINT64 PagedPoolCharge; 
  UINT64 NonPagedPoolCharge; 
  _TOKEN *NewToken; 
  _AUTHZBASEP_SECURITY_ATTRIBUTES_INFORMATION **p_pSecurityAttributes; 
  VOID *NewSid; 
  unsigned int *p_RestrictedSidCount; 
  _QWORD *p_DynamicPart; 
  _SEP_LOWBOX_NUMBER_ENTRY **p_LowboxNumberEntry; 
  _SEP_CACHED_HANDLES_ENTRY **p_LowboxHandlesEntry; 
  _SEP_CACHED_HANDLES_ENTRY **p_BnoIsolationHandlesEntry; 
  PVOID *p_TrustLevelSid; 
  _SID_AND_ATTRIBUTES **p_Capabilities; 
  _SID_AND_ATTRIBUTES_HASH *SidAttrHash; 
  unsigned int *p_CapabilityCount; 
  UINT64 puResult; 

  v8 = ImpersonationLevel;
  NewToken = 0i64;
  LODWORD(puResult) = 0;
  v11 = 0i64;
  if( TokenType == TokenImpersonation && (unsigned int)ImpersonationLevel > SecurityDelegation )
    return -1073741659;
  PoolWithTag = ExAllocatePoolWithTag(1ui64, 0x30ui64, 1950442835i64);
  v14 = PoolWithTag;
  if( !PoolWithTag )
    return -1073741670;
  *(_DWORD *)PoolWithTag = 0;
  v15 = PoolWithTag + 1;
  *((_DWORD *)v14 + 6) = 0;
  v15[1] = v15;
  *v15 = v15;
  v14[5] = v14 + 4;
  v14[4] = v14 + 4;
  if( SeTokenLeakTracking )
  {
    v11 = ExAllocatePoolWithTag(1ui64, 0x120ui64, 1950442835i64);
    if( !v11 )
    {
      v16 = v14;
      goto LABEL_8;
    }
  }
  v17 = ExAllocatePoolWithTag(0x200ui64, 0x68ui64, 1817470291i64);
  if( !v17 )
  {
    ExFreePoolWithTag(v14, 0);
    if( !SeTokenLeakTracking )
      return -1073741670;
    v16 = v11;
LABEL_8:
    ExFreePoolWithTag(v16, 0);
    return -1073741670;
  }
  Object = RtlULongAdd(0x490ui64, ExistingToken->VariableLength, &puResult);
  if( Object < 0
    || (LODWORD(NonPagedPoolCharge) = puResult,
        LODWORD(PagedPoolCharge) = ExistingToken->DynamicCharged,
        LODWORD(ObjectBodySize) = puResult,
        Object = ObCreateObjectEx(
                   (unsigned __int8)RequestorMode,
                   (_OBJECT_TYPE *)SeTokenObjectType,
                   ObjectAttributes,
                   (unsigned __int8)RequestorMode,
                   v57,
                   ObjectBodySize,
                   PagedPoolCharge,
                   NonPagedPoolCharge,
                   (VOID **)&NewToken,
                   0i64),
        Object < 0) )
  {
    ExFreePoolWithTag(v14, 0);
    ExFreePoolWithTag(v17, 0);
    if( SeTokenLeakTracking )
      ExFreePoolWithTag(v11, 0);
    return Object;
  }
  v19 = NewToken;
  NewToken->TokenId = (_LUID)(ExpLuidIncrement + _InterlockedExchangeAdd64(&ExpLuid, ExpLuidIncrement));
  v19->TokenInUse = 0;
  v19->TokenType = TokenType;
  v19->ImpersonationLevel = v8;
  v19->TokenLock = (_ERESOURCE *)v17;
  ExInitializeResourceLite((INT64)v17);
  v19->AuthenticationId = ExistingToken->AuthenticationId;
  v19->TokenSource = ExistingToken->TokenSource;
  v19->DynamicAvailable = 0;
  v19->ParentTokenId = ExistingToken->ParentTokenId;
  v19->ExpirationTime.QuadPart = ExistingToken->ExpirationTime.QuadPart;
  v19->OriginatingLogonSession = ExistingToken->OriginatingLogonSession;
  v19->IntegrityLevelSidValue = 0i64;
  v19->TokenSidValues = 0i64;
  v19->pClaimAttributes = 0i64;
  v19->DiagnosticInfo = (_SEP_TOKEN_DIAG_TRACK_ENTRY *)v11;
  v19->SessionId = 0;
  v19->SessionObject = 0i64;
  if( SeTokenLeakTracking )
  {
    v20 = RtlWalkFrameChain((INT64)(v11 + 5), 30i64, 0i64);
    if( KeGetCurrentIrql() < 2u )
      RtlWalkFrameChain((INT64)&v19->DiagnosticInfo->CreateTrace[v20], 30 - v20, 1ui64);
  }
  CurrentThread = (_ETHREAD *)KeGetCurrentThread();
  --CurrentThread->Tcb.KernelApcDisable;
  ExAcquireResourceSharedLite((UINT64)ExistingToken->TokenLock, 1);
  v22 = NewToken;
  NewToken->ModifiedId = ExistingToken->ModifiedId;
  v22->DynamicCharged = ExistingToken->DynamicCharged;
  v22->DefaultOwnerIndex = ExistingToken->DefaultOwnerIndex;
  v22->RestrictedSidCount = ExistingToken->RestrictedSidCount;
  v22->VariableLength = ExistingToken->VariableLength;
  v23 = ExistingToken->TokenFlags & 0xFFFFFBDF;
  p_RestrictedSidCount = &v22->RestrictedSidCount;
  v22->TokenFlags = v23;
  SessionId = ExistingToken->SessionId;
  if( v19->SessionId != SessionId )
  {
    v19->SessionId = SessionId;
    if( !SeTokenDoesNotTrackSessionObject )
    {
      SessionObject = (_ADAPTER_OBJECT *)v19->SessionObject;
      if( SessionObject )
        HalPutDmaAdapter(SessionObject);
      v19->SessionObject = MmGetSessionObjectById(SessionId);
    }
  }
  v19->SessionId = ExistingToken->SessionId;
  *(_OWORD *)v22->AuditPolicy.AdtTokenPolicy.PerUserPolicy = *(_OWORD *)ExistingToken->AuditPolicy.AdtTokenPolicy.PerUserPolicy;
  *(_QWORD *)&v22->AuditPolicy.AdtTokenPolicy.PerUserPolicy[16] = *(_QWORD *)&ExistingToken->AuditPolicy.AdtTokenPolicy.PerUserPolicy[16];
  *(_DWORD *)&v22->AuditPolicy.AdtTokenPolicy.PerUserPolicy[24] = *(_DWORD *)&ExistingToken->AuditPolicy.AdtTokenPolicy.PerUserPolicy[24];
  *(_WORD *)&v22->AuditPolicy.AdtTokenPolicy.PerUserPolicy[28] = *(_WORD *)&ExistingToken->AuditPolicy.AdtTokenPolicy.PerUserPolicy[28];
  v22->AuditPolicy.PolicySetStatus = ExistingToken->AuditPolicy.PolicySetStatus;
  v22->IntegrityLevelIndex = ExistingToken->IntegrityLevelIndex;
  v22->MandatoryPolicy = ExistingToken->MandatoryPolicy;
  v26 = *(_OWORD *)&ExistingToken->Privileges.Present;
  p_pSecurityAttributes = &v22->pSecurityAttributes;
  *(_OWORD *)&v22->Privileges.Present = v26;
  v22->Privileges.EnabledByDefault = ExistingToken->Privileges.EnabledByDefault;
  v22->pSecurityAttributes = (_AUTHZBASEP_SECURITY_ATTRIBUTES_INFORMATION *)v14;
  v22->LowboxNumberEntry = 0i64;
  p_LowboxNumberEntry = &v22->LowboxNumberEntry;
  v22->LowboxHandlesEntry = 0i64;
  p_LowboxHandlesEntry = &v22->LowboxHandlesEntry;
  v22->BnoIsolationHandlesEntry = 0i64;
  p_BnoIsolationHandlesEntry = &v22->BnoIsolationHandlesEntry;
  v22->Capabilities = 0i64;
  p_Capabilities = &v22->Capabilities;
  v22->Package = 0i64;
  p_CapabilityCount = &v22->CapabilityCount;
  v22->CapabilityCount = 0;
  SidAttrHash = &v22->CapabilitiesHash;
  memset(&v22->CapabilitiesHash, 0i64, sizeof(v22->CapabilitiesHash));
  v22->DynamicPart = 0i64;
  p_DynamicPart = &v22->DynamicPart;
  v22->TrustLevelSid = 0i64;
  v22->TrustLinkedToken = 0i64;
  p_IndexEntry = &v22->IndexEntry;
  v22->IndexEntry = 0i64;
  v28 = v22->AuditPolicy.PolicySetStatus == 2;
  p_TrustLevelSid = &v22->TrustLevelSid;
  if( v28 )
    SepModifyTokenPolicyCounter(&v22->AuditPolicy, 1u);
  if( (ExistingToken->TokenFlags & 0x20) != 0 )
  {
    v30 = SepReferenceLogonSession(&ExistingToken->AuthenticationId, &v22->LogonSession);
    if( v30 < 0 )
    {
      v22->TokenFlags |= 0x20u;
      v22->LogonSession = 0i64;
    }
    if( v30 < 0 )
      goto LABEL_42;
  }
  else
  {
    LogonSession = ExistingToken->LogonSession;
    v22->LogonSession = LogonSession;
    if( _InterlockedIncrement64(&LogonSession->ReferenceCount) <= 1 )
      __fastfail(0xEu);
    v22 = NewToken;
    v30 = 0;
  }
  IndexEntry = ExistingToken->IndexEntry;
  if( IndexEntry )
  {
    SepReferenceLuidToIndexEntry(ExistingToken->IndexEntry);
    IndexEntry = ExistingToken->IndexEntry;
  }
  *p_IndexEntry = IndexEntry;
  pSecurityAttributes = ExistingToken->pSecurityAttributes;
  if( *(_DWORD *)pSecurityAttributes )
  {
    v30 = AuthzBasepDuplicateSecurityAttributes(
            pSecurityAttributes,
            *p_pSecurityAttributes,
            SkipNonInheritableSecurityAttributes);
    if( v30 < 0 )
    {
LABEL_42:
      ExReleaseResourceLite(ExistingToken->TokenLock);
      KeLeaveCriticalRegion();
LABEL_43:
      HalPutDmaAdapter((PADAPTER_OBJECT)v22);
      return v30;
    }
  }
  memmove(&v22->VariablePart, &ExistingToken->VariablePart, ExistingToken->VariableLength);
  p_UserAndGroups = &v22->UserAndGroups;
  v34 = (char *)v22 - (char *)ExistingToken;
  if( SepTokenSidSharingEnabled )
  {
    *p_UserAndGroups = (_SID_AND_ATTRIBUTES *)((char *)ExistingToken->UserAndGroups + v34);
    v30 = SepDuplicateTokenUserAndGroups(ExistingToken, v22);
    if( v30 < 0 )
    {
      *p_UserAndGroups = 0i64;
      goto LABEL_42;
    }
  }
  else
  {
    v22->UserAndGroupCount = ExistingToken->UserAndGroupCount;
    v35 = (_SID_AND_ATTRIBUTES *)((char *)ExistingToken->UserAndGroups + v34);
    *p_UserAndGroups = v35;
    for( i = v22->UserAndGroupCount; i; --i )
    {
      v35->Sid = (char *)v35->Sid + v34;
      ++v35;
    }
  }
  RestrictedSids = ExistingToken->RestrictedSids;
  p_pSecurityAttributes = (_AUTHZBASEP_SECURITY_ATTRIBUTES_INFORMATION **)&v22->RestrictedSids;
  v22->RestrictedSids = RestrictedSids;
  if( RestrictedSids )
  {
    v38 = (_SID_AND_ATTRIBUTES *)((char *)RestrictedSids + v34);
    v22->RestrictedSids = v38;
    for( j = *p_RestrictedSidCount; j; --j )
    {
      v38->Sid = (char *)v38->Sid + v34;
      ++v38;
    }
  }
  DefaultDacl = ExistingToken->DefaultDacl;
  v41 = 4 * *((unsigned __int8 *)ExistingToken->PrimaryGroup + 1) + 8;
  if( DefaultDacl )
    v41 += DefaultDacl->AclSize;
  v42 = v41;
  v43 = ExAllocatePoolWithTag(1ui64, v41, 1683252563i64);
  *p_DynamicPart = v43;
  if( !v43 )
  {
    ExReleaseResourceLite(ExistingToken->TokenLock);
    KeLeaveCriticalRegion();
    HalPutDmaAdapter((PADAPTER_OBJECT)v22);
    return -1073741670;
  }
  memmove(v43, ExistingToken->DynamicPart, v42);
  v44 = ExistingToken->DefaultDacl;
  v45 = (char *)v43 - (char *)ExistingToken->DynamicPart;
  v22->DefaultDacl = v44;
  if( v44 )
    v22->DefaultDacl = (_ACL *)((char *)v44 + v45);
  v22->PrimaryGroup = (char *)ExistingToken->PrimaryGroup + v45;
  CapabilityCount = ExistingToken->CapabilityCount;
  if( (_DWORD)CapabilityCount )
    v30 = SepSetTokenCapabilities(v22, ExistingToken->Package, ExistingToken->Capabilities, CapabilityCount);
  if( v30 < 0 )
    goto LABEL_42;
  Package = ExistingToken->Package;
  if( Package )
    v30 = SepSetTokenPackage(v22, Package);
  if( v30 < 0 )
    goto LABEL_42;
  LowboxNumberEntry = ExistingToken->LowboxNumberEntry;
  if( LowboxNumberEntry )
  {
    if( _InterlockedIncrement64(&LowboxNumberEntry->ReferenceCount) <= 1 )
      __fastfail(0xEu);
    v22 = NewToken;
    *p_LowboxNumberEntry = ExistingToken->LowboxNumberEntry;
  }
  LowboxHandlesEntry = ExistingToken->LowboxHandlesEntry;
  if( LowboxHandlesEntry )
  {
    if( _InterlockedIncrement64(&LowboxHandlesEntry->ReferenceCount) <= 1 )
      __fastfail(0xEu);
    v22 = NewToken;
    *p_LowboxHandlesEntry = ExistingToken->LowboxHandlesEntry;
  }
  BnoIsolationHandlesEntry = ExistingToken->BnoIsolationHandlesEntry;
  if( BnoIsolationHandlesEntry )
  {
    if( _InterlockedIncrement64(&BnoIsolationHandlesEntry->ReferenceCount) <= 1 )
      __fastfail(0xEu);
    v22 = NewToken;
    *p_BnoIsolationHandlesEntry = ExistingToken->BnoIsolationHandlesEntry;
  }
  if( ExistingToken->pClaimAttributes )
  {
    v30 = SepDuplicateTokenClaims(ExistingToken, v22);
    if( v30 < 0 )
      goto LABEL_42;
  }
  TrustLevelSid = ExistingToken->TrustLevelSid;
  v52 = 0i64;
  v30 = 0;
  NewSid = 0i64;
  if( TrustLevelSid )
  {
    v30 = SepDuplicateSid(TrustLevelSid, &NewSid);
    if( v30 < 0 )
      goto LABEL_81;
    v52 = NewSid;
  }
  v53 = p_TrustLevelSid;
  if( *p_TrustLevelSid )
  {
    ExFreePoolWithTag(*p_TrustLevelSid, 0);
    *v53 = 0i64;
  }
  *v53 = v52;
LABEL_81:
  ExReleaseResourceLite(ExistingToken->TokenLock);
  KeLeaveCriticalRegion();
  if( v30 < 0 )
    goto LABEL_43;
  if( SeTokenLeakTracking )
  {
    v19->DiagnosticInfo->ProcessCid = (void *)KeGetCurrentThread()[1].CycleTime;
    v19->DiagnosticInfo->ThreadCid = *(void **)&KeGetCurrentThread()[1].CurrentRunTime;
    v19->DiagnosticInfo->CreateMethod = 13;
    v19->DiagnosticInfo->Count = 0;
    v19->DiagnosticInfo->CaptureCount = 0;
    DiagnosticInfo = v19->DiagnosticInfo;
    v22 = NewToken;
    Process = KeGetCurrentThread()->ApcState.Process;
    *(_QWORD *)DiagnosticInfo->ImageFileName = *(_QWORD *)Process->ImageFileName;
    *(_DWORD *)&DiagnosticInfo->ImageFileName[8] = *(_DWORD *)&Process->ImageFileName[8];
    *(_WORD *)&DiagnosticInfo->ImageFileName[12] = *(_WORD *)&Process->ImageFileName[12];
    DiagnosticInfo->ImageFileName[14] = Process->ImageFileName[14];
    SepAddTokenLogonSession(v22);
  }
  if( EffectiveOnly )
    SepMakeTokenEffectiveOnly(v22);
  RtlSidHashInitialize(*p_UserAndGroups, v22->UserAndGroupCount, &v22->SidHash);
  RtlSidHashInitialize((_SID_AND_ATTRIBUTES *)*p_pSecurityAttributes, *p_RestrictedSidCount, &v22->RestrictedSidHash);
  if( *p_Capabilities )
    RtlSidHashInitialize(*p_Capabilities, *p_CapabilityCount, SidAttrHash);
  if( SeTokenLeakTracking && SepTokenLeakMethodWatch == 13 )
  {
    if( KeGetCurrentThread()->ApcState.Process->UniqueProcessId == (void *)SepTokenLeakProcessCid )
    {
      v19->DiagnosticInfo->Count = _InterlockedIncrement(&SepTokenLeakMethodCount);
      Count = (unsigned int)v19->DiagnosticInfo->Count;
      if( (int)Count >= SepTokenLeakBreakCount )
      {
        DbgPrint("\nToken number 0x%x = 0x%p\n", Count, NewToken);
        __debugbreak();
      }
    }
    v22 = NewToken;
  }
  *DuplicateToken = v22;
  return v30;
}

Referenced by:

NtCreateLowBoxToken
NtDuplicateToken
NtImpersonateAnonymousToken
NtOpenThreadTokenEx
NtQueryInformationToken
SeCopyClientToken
SeDuplicateTokenAndAddOriginClaim
SeGetLinkedToken
SeGetLogonSessionToken
SeSubProcessToken
SepGetAnonymousToken
SepLinkLogonSessions
SepSetLogonSessionToken