SepDuplicateToken

INT64 __fastcall SepDuplicateToken(
        _TOKEN *ExistingToken,
        _OBJECT_ATTRIBUTES *ObjectAttributes,
        UINT8 EffectiveOnly,
        _TOKEN_TYPE TokenType,
        _SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
        CHAR RequestorMode,
        UINT8 SkipNonInheritableSecurityAttributes,
        _TOKEN **DuplicateToken){
  _SECURITY_IMPERSONATION_LEVEL v8; 
  VOID **v11; 
  _DWORD *PoolWithTag; 
  _DWORD *v14; 
  _QWORD *v15; 
  VOID **v16; 
  struct _ERESOURCE *v17; 
  int v18; 
  PADAPTER_OBJECT v19; 
  unsigned int v20; 
  _ETHREAD *CurrentThread; 
  PADAPTER_OBJECT v22; 
  unsigned int v23; 
  unsigned int SessionId; 
  struct _DMA_ADAPTER *DmaOperations; 
  _DMA_OPERATIONS *v26; 
  struct _DMA_ADAPTER v27; 
  _QWORD *v28; 
  bool v29; 
  _SEP_LOGON_SESSION_REFERENCES *LogonSession; 
  int v31; 
  _SEP_LUID_TO_INDEX_MAP_ENTRY *IndexEntry; 
  _AUTHZBASEP_SECURITY_ATTRIBUTES_INFORMATION *pSecurityAttributes; 
  SID_AND_ATTRIBUTES **v34; 
  signed __int64 v35; 
  SID_AND_ATTRIBUTES *v36; 
  int i; 
  _SID_AND_ATTRIBUTES *RestrictedSids; 
  _QWORD *v39; 
  int j; 
  _ACL *DefaultDacl; 
  unsigned int v42; 
  UINT64 v43; 
  UINT8 *v44; 
  INT64 v45; 
  _ACL *v46; 
  signed __int64 v47; 
  UINT64 CapabilityCount; 
  UINT8 *Package; 
  _SEP_LOWBOX_NUMBER_ENTRY *LowboxNumberEntry; 
  _SEP_CACHED_HANDLES_ENTRY *LowboxHandlesEntry; 
  _SEP_CACHED_HANDLES_ENTRY *BnoIsolationHandlesEntry; 
  void *TrustLevelSid; 
  VOID *v54; 
  PVOID *v55; 
  _DMA_OPERATIONS *v56; 
  __int64 v57; 
  __int64 AllocateCommonBufferVector_low; 
  __int64 v59; 
  RTL_DYNAMIC_HASH_TABLE_ENUMERATOR **v60; 
  PADAPTER_OBJECT DmaAdapter; 
  _AUTHZBASEP_SECURITY_ATTRIBUTES_INFORMATION **p_DmaOperations; 
  VOID *NewSid; 
  struct _DMA_ADAPTER *v64; 
  _QWORD *v65; 
  _QWORD *v66; 
  _QWORD *p_Version; 
  _QWORD *v68; 
  PVOID *v69; 
  SID_AND_ATTRIBUTES **v70; 
  SID_AND_ATTRIBUTES_HASH *SidAttrHash; 
  struct _DMA_ADAPTER *v72; 
  UINT64 pulResult; 
  v8 = ImpersonationLevel;
  DmaAdapter = 0i64;
  LODWORD(pulResult) = 0;
  v11 = 0i64;
  if( TokenType == TokenImpersonation && (unsigned int)ImpersonationLevel > SecurityDelegation )
    return 3221225637i64;
  PoolWithTag = ExAllocatePoolWithTag(PagedPool, 0x30ui64, 0x74416553ui64);
  v14 = PoolWithTag;
  if( !PoolWithTag )
    return 3221225626i64;
  *PoolWithTag = 0;
  v15 = PoolWithTag + 2;
  v14[6] = 0;
  v15[1] = v15;
  *v15 = v15;
  *((_QWORD *)v14 + 5) = v14 + 8;
  *((_QWORD *)v14 + 4) = v14 + 8;
  if( SeTokenLeakTracking )
  {
    v11 = (VOID **)ExAllocatePoolWithTag(PagedPool, 0x120ui64, 0x74416553ui64);
    if( !v11 )
    {
      v16 = (VOID **)v14;
      goto LABEL_8;
    }
  }
  v17 = (struct _ERESOURCE *)ExAllocatePoolWithTag(NonPagedPoolNx, 0x68ui64, 0x6C546553ui64);
  if( !v17 )
  {
    ExFreePoolWithTag(v14, 0);
    if( !SeTokenLeakTracking )
      return 3221225626i64;
    v16 = v11;
LABEL_8:
    ExFreePoolWithTag(v16, 0);
    return 3221225626i64;
  }
  v18 = RtlULongAdd(0x490ui64, ExistingToken->VariableLength, &pulResult);
  if( v18 < 0
    || (v18 = ObCreateObjectEx(
                RequestorMode,
                SeTokenObjectType,
                (__int64)ObjectAttributes,
                RequestorMode,
                v59,
                pulResult,
                ExistingToken->DynamicCharged,
                pulResult,
                &DmaAdapter,
                0i64),
        v18 < 0) )
  {
    ExFreePoolWithTag(v14, 0);
    ExFreePoolWithTag(v17, 0);
    if( SeTokenLeakTracking )
      ExFreePoolWithTag(v11, 0);
    return(unsigned int)v18;
  }
  v19 = DmaAdapter;
  *(_QWORD *)&DmaAdapter[1].Version = ExpLuidIncrement + _InterlockedExchangeAdd64(&ExpLuid, ExpLuidIncrement);
  BYTE4(v19[12].DmaOperations) = 0;
  *(_DWORD *)&v19[12].Version = TokenType;
  *(_DWORD *)(&v19[12].Size + 1) = v8;
  *(_QWORD *)&v19[3].Version = v17;
  ExInitializeResourceLite(v17);
  v19[1].DmaOperations = (_DMA_OPERATIONS *)ExistingToken->AuthenticationId;
  *v19 = (struct _DMA_ADAPTER)ExistingToken->TokenSource;
  HIDWORD(v19[8].DmaOperations) = 0;
  v19[2] = *(struct _DMA_ADAPTER *)&ExistingToken->ParentTokenId.LowPart;
  *(_LUID *)&v19[14].Version = ExistingToken->OriginatingLogonSession;
  *(_QWORD *)&v19[70].Version = 0i64;
  v19[70].DmaOperations = 0i64;
  v19[68].DmaOperations = 0i64;
  v19[71].DmaOperations = (_DMA_OPERATIONS *)v11;
  LODWORD(v19[7].DmaOperations) = 0;
  v19[72].DmaOperations = 0i64;
  if( SeTokenLeakTracking )
  {
    v20 = RtlWalkFrameChain(v11 + 5, 0x1Eui64, 0i64);
    if( KeGetCurrentIrql() < 2u )
      RtlWalkFrameChain((VOID **)&v19[71].DmaOperations->FlushAdapterBuffers + v20, 30 - v20, 1ui64);
  }
  CurrentThread = (_ETHREAD *)KeGetCurrentThread();
  --*((_WORD *)CurrentThread + 242);
  ExAcquireResourceSharedLite(ExistingToken->TokenLock, 1);
  v22 = DmaAdapter;
  DmaAdapter[3].DmaOperations = (_DMA_OPERATIONS *)ExistingToken->ModifiedId;
  LODWORD(v22[8].DmaOperations) = ExistingToken->DynamicCharged;
  *(_DWORD *)&v22[9].Version = ExistingToken->DefaultOwnerIndex;
  *(_DWORD *)&v22[8].Version = ExistingToken->RestrictedSidCount;
  *(_DWORD *)(&v22[8].Size + 1) = ExistingToken->VariableLength;
  v23 = ExistingToken->TokenFlags & 0xFFFFFBDF;
  v64 = v22 + 8;
  LODWORD(v22[12].DmaOperations) = v23;
  SessionId = ExistingToken->SessionId;
  if( LODWORD(v19[7].DmaOperations) != SessionId )
  {
    LODWORD(v19[7].DmaOperations) = SessionId;
    if( !SeTokenDoesNotTrackSessionObject )
    {
      DmaOperations = (struct _DMA_ADAPTER *)v19[72].DmaOperations;
      if( DmaOperations )
        HalPutDmaAdapter(DmaOperations);
      LODWORD(v26) = MmGetSessionObjectById(SessionId);
      v19[72].DmaOperations = v26;
    }
  }
  LODWORD(v19[7].DmaOperations) = ExistingToken->SessionId;
  *(PADAPTER_OBJECT)((char *)v22 + 88) = *(PADAPTER_OBJECT)ExistingToken->AuditPolicy.AdtTokenPolicy.PerUserPolicy;
  v22[6].DmaOperations = *(_DMA_OPERATIONS **)&ExistingToken->AuditPolicy.AdtTokenPolicy.PerUserPolicy[16];
  *(_DWORD *)&v22[7].Version = *(_DWORD *)&ExistingToken->AuditPolicy.AdtTokenPolicy.PerUserPolicy[24];
  *(&v22[7].Size + 1) = *(_WORD *)&ExistingToken->AuditPolicy.AdtTokenPolicy.PerUserPolicy[28];
  *((_BYTE *)&v22[7].Size + 4) = ExistingToken->AuditPolicy.PolicySetStatus;
  *(_DWORD *)&v22[13].Version = ExistingToken->IntegrityLevelIndex;
  *(_DWORD *)(&v22[13].Size + 1) = ExistingToken->MandatoryPolicy;
  v27 = *(struct _DMA_ADAPTER *)&ExistingToken->Privileges.Present;
  p_DmaOperations = (_AUTHZBASEP_SECURITY_ATTRIBUTES_INFORMATION **)&v22[48].DmaOperations;
  v22[4] = v27;
  *(_QWORD *)&v22[5].Version = ExistingToken->Privileges.EnabledByDefault;
  v22[48].DmaOperations = (_DMA_OPERATIONS *)v14;
  v22[67].DmaOperations = 0i64;
  v66 = &v22[67].DmaOperations;
  *(_QWORD *)&v22[68].Version = 0i64;
  p_Version = &v22[68].Version;
  *(_QWORD *)&v22[72].Version = 0i64;
  v68 = &v22[72].Version;
  v22[49].DmaOperations = 0i64;
  v70 = (SID_AND_ATTRIBUTES **)&v22[49].DmaOperations;
  *(_QWORD *)&v22[49].Version = 0i64;
  v72 = v22 + 50;
  *(_DWORD *)&v22[50].Version = 0;
  SidAttrHash = (SID_AND_ATTRIBUTES_HASH *)&v22[50].DmaOperations;
  memset((INT64)&v22[50].DmaOperations, 0i64);
  *(_QWORD *)&v22[11].Version = 0i64;
  v65 = &v22[11].Version;
  *(_QWORD *)&v22[69].Version = 0i64;
  v22[69].DmaOperations = 0i64;
  v28 = &v22[71].Version;
  *(_QWORD *)&v22[71].Version = 0i64;
  v29 = *((_BYTE *)&v22[7].Size + 4) == 2;
  v69 = (PVOID *)&v22[69];
  if( v29 )
    SepModifyTokenPolicyCounter((_SEP_AUDIT_POLICY *)&v22[5].DmaOperations, 1u);
  if( (ExistingToken->TokenFlags & 0x20) != 0 )
  {
    v31 = SepReferenceLogonSession(&ExistingToken->AuthenticationId, (__int64 *)&v22[13].DmaOperations);
    if( v31 < 0 )
    {
      LODWORD(v22[12].DmaOperations) |= 0x20u;
      v22[13].DmaOperations = 0i64;
    }
    if( v31 < 0 )
      goto LABEL_42;
  }
  else
  {
    LogonSession = ExistingToken->LogonSession;
    v22[13].DmaOperations = (_DMA_OPERATIONS *)LogonSession;
    if( _InterlockedIncrement64(&LogonSession->ReferenceCount) <= 1 )
      __fastfail(0xEu);
    v22 = DmaAdapter;
    v31 = 0;
  }
  IndexEntry = ExistingToken->IndexEntry;
  if( IndexEntry )
  {
    SepReferenceLuidToIndexEntry((INT64)ExistingToken->IndexEntry);
    IndexEntry = ExistingToken->IndexEntry;
  }
  *v28 = IndexEntry;
  pSecurityAttributes = ExistingToken->pSecurityAttributes;
  if( pSecurityAttributes->SecurityAttributeCount )
  {
    v31 = AuthzBasepDuplicateSecurityAttributes(
            pSecurityAttributes,
            *p_DmaOperations,
            SkipNonInheritableSecurityAttributes);
    if( v31 < 0 )
    {
LABEL_42:
      ExReleaseResourceLite(ExistingToken->TokenLock);
      KeLeaveCriticalRegion();
LABEL_43:
      HalPutDmaAdapter(v22);
      return(unsigned int)v31;
    }
  }
  memmove((UINT8 *)&v22[73], (UINT8 *)&ExistingToken->VariablePart, ExistingToken->VariableLength);
  v34 = (SID_AND_ATTRIBUTES **)&v22[9].DmaOperations;
  v35 = (char *)v22 - (char *)ExistingToken;
  if( SepTokenSidSharingEnabled )
  {
    *v34 = (_SID_AND_ATTRIBUTES *)((char *)ExistingToken->UserAndGroups + v35);
    v31 = SepDuplicateTokenUserAndGroups(ExistingToken, (_TOKEN *)v22);
    if( v31 < 0 )
    {
      *v34 = 0i64;
      goto LABEL_42;
    }
  }
  else
  {
    HIDWORD(v22[7].DmaOperations) = ExistingToken->UserAndGroupCount;
    v36 = (_SID_AND_ATTRIBUTES *)((char *)ExistingToken->UserAndGroups + v35);
    *v34 = v36;
    for( i = HIDWORD(v22[7].DmaOperations); i; --i )
    {
      v36->Sid = (char *)v36->Sid + v35;
      ++v36;
    }
  }
  RestrictedSids = ExistingToken->RestrictedSids;
  p_DmaOperations = (_AUTHZBASEP_SECURITY_ATTRIBUTES_INFORMATION **)&v22[10];
  *(_QWORD *)&v22[10].Version = RestrictedSids;
  if( RestrictedSids )
  {
    v39 = (void **)((char *)&RestrictedSids->Sid + v35);
    *(_QWORD *)&v22[10].Version = v39;
    for( j = *(_DWORD *)&v64->Version; j; --j )
    {
      *v39 += v35;
      v39 += 2;
    }
  }
  DefaultDacl = ExistingToken->DefaultDacl;
  v42 = 4 * *((unsigned __int8 *)ExistingToken->PrimaryGroup + 1) + 8;
  if( DefaultDacl )
    v42 += DefaultDacl->AclSize;
  v43 = v42;
  v44 = (UINT8 *)ExAllocatePoolWithTag(PagedPool, v42, 0x64546553ui64);
  *v65 = v44;
  if( !v44 )
  {
    ExReleaseResourceLite(ExistingToken->TokenLock);
    KeLeaveCriticalRegion();
    HalPutDmaAdapter(v22);
    return 3221225626i64;
  }
  memmove(v44, (UINT8 *)ExistingToken->DynamicPart, v43);
  v46 = ExistingToken->DefaultDacl;
  v47 = v44 - (UINT8 *)ExistingToken->DynamicPart;
  v22[11].DmaOperations = (_DMA_OPERATIONS *)v46;
  if( v46 )
    v22[11].DmaOperations = (_DMA_OPERATIONS *)((char *)v46 + v47);
  v22[10].DmaOperations = (_DMA_OPERATIONS *)((char *)ExistingToken->PrimaryGroup + v47);
  CapabilityCount = ExistingToken->CapabilityCount;
  if( (_DWORD)CapabilityCount )
    v31 = SepSetTokenCapabilities((_TOKEN *)v22, ExistingToken->Package, ExistingToken->Capabilities, CapabilityCount);
  if( v31 < 0 )
    goto LABEL_42;
  Package = (UINT8 *)ExistingToken->Package;
  if( Package )
    v31 = SepSetTokenPackage((INT64)v22, Package);
  if( v31 < 0 )
    goto LABEL_42;
  LowboxNumberEntry = ExistingToken->LowboxNumberEntry;
  if( LowboxNumberEntry )
  {
    if( _InterlockedIncrement64(&LowboxNumberEntry->ReferenceCount) <= 1 )
      __fastfail(0xEu);
    v22 = DmaAdapter;
    *v66 = ExistingToken->LowboxNumberEntry;
  }
  LowboxHandlesEntry = ExistingToken->LowboxHandlesEntry;
  if( LowboxHandlesEntry )
  {
    if( _InterlockedIncrement64(&LowboxHandlesEntry->ReferenceCount) <= 1 )
      __fastfail(0xEu);
    v22 = DmaAdapter;
    *p_Version = ExistingToken->LowboxHandlesEntry;
  }
  BnoIsolationHandlesEntry = ExistingToken->BnoIsolationHandlesEntry;
  if( BnoIsolationHandlesEntry )
  {
    if( _InterlockedIncrement64(&BnoIsolationHandlesEntry->ReferenceCount) <= 1 )
      __fastfail(0xEu);
    v22 = DmaAdapter;
    *v68 = ExistingToken->BnoIsolationHandlesEntry;
  }
  if( ExistingToken->pClaimAttributes )
  {
    v31 = SepDuplicateTokenClaims(
            (RTL_DYNAMIC_HASH_TABLE *)ExistingToken,
            (INT64)v22,
            v45,
            (RTL_DYNAMIC_HASH_TABLE_ENUMERATOR **)CapabilityCount,
            v60);
    if( v31 < 0 )
      goto LABEL_42;
  }
  TrustLevelSid = ExistingToken->TrustLevelSid;
  v54 = 0i64;
  v31 = 0;
  NewSid = 0i64;
  if( TrustLevelSid )
  {
    v31 = SepDuplicateSid(TrustLevelSid, &NewSid);
    if( v31 < 0 )
      goto LABEL_81;
    v54 = NewSid;
  }
  v55 = v69;
  if( *v69 )
  {
    ExFreePoolWithTag(*v69, 0);
    *v55 = 0i64;
  }
  *v55 = v54;
LABEL_81:
  ExReleaseResourceLite(ExistingToken->TokenLock);
  KeLeaveCriticalRegion();
  if( v31 < 0 )
    goto LABEL_43;
  if( SeTokenLeakTracking )
  {
    *(_QWORD *)v19[71].DmaOperations = *((_QWORD *)KeGetCurrentThread() + 143);
    v19[71].DmaOperations->PutDmaAdapter = (void(__fastcall *)(_DMA_ADAPTER *))*((_QWORD *)KeGetCurrentThread() + 144);
    LODWORD(v19[71].DmaOperations->AllocateAdapterChannel) = 13;
    LODWORD(v19[71].DmaOperations->AllocateCommonBufferVector) = 0;
    HIDWORD(v19[71].DmaOperations->AllocateCommonBufferVector) = 0;
    v56 = v19[71].DmaOperations;
    v22 = DmaAdapter;
    v57 = *((_QWORD *)KeGetCurrentThread() + 23);
    v56->AllocateCommonBuffer = *(void *(__fastcall **)(_DMA_ADAPTER *, unsigned int, _LARGE_INTEGER *, unsigned __int8))(v57 + 1448);
    LODWORD(v56->FreeCommonBuffer) = *(_DWORD *)(v57 + 1456);
    WORD2(v56->FreeCommonBuffer) = *(_WORD *)(v57 + 1460);
    BYTE6(v56->FreeCommonBuffer) = *(_BYTE *)(v57 + 1462);
    SepAddTokenLogonSession((INT64)v22);
  }
  if( EffectiveOnly )
    SepMakeTokenEffectiveOnly((INT64)v22);
  RtlSidHashInitialize(*v34, HIDWORD(v22[7].DmaOperations), (SID_AND_ATTRIBUTES_HASH *)&v22[14].DmaOperations);
  RtlSidHashInitialize(
    (SID_AND_ATTRIBUTES *)*p_DmaOperations,
    *(unsigned int *)&v64->Version,
    (SID_AND_ATTRIBUTES_HASH *)&v22[31].DmaOperations);
  if( *v70 )
    RtlSidHashInitialize(*v70, *(unsigned int *)&v72->Version, SidAttrHash);
  if( SeTokenLeakTracking && SepTokenLeakMethodWatch == 13 )
  {
    if( *(_QWORD *)(*((_QWORD *)KeGetCurrentThread() + 23) + 1088i64) == SepTokenLeakProcessCid )
    {
      LODWORD(v19[71].DmaOperations->AllocateCommonBufferVector) = _InterlockedIncrement(&SepTokenLeakMethodCount);
      AllocateCommonBufferVector_low = LODWORD(v19[71].DmaOperations->AllocateCommonBufferVector);
      if( (int)AllocateCommonBufferVector_low >= SepTokenLeakBreakCount )
      {
        DbgPrint("\nToken number 0x%x = 0x%p\n", AllocateCommonBufferVector_low, DmaAdapter);
        __debugbreak();
      }
    }
    v22 = DmaAdapter;
  }
  *DuplicateToken = (_TOKEN *)v22;
  return(unsigned int)v31;
}

Referenced by:

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