PsImpersonateClient

NTSTATUS __stdcall PsImpersonateClient(
        PETHREAD Thread,
        VOID *Token,
        BOOL CopyOnOpen,
        BOOL EffectiveOnly,
        _SECURITY_IMPERSONATION_LEVEL ImpersonationLevel){
  _EPROCESS *Process; 
  char v6; 
  unsigned __int64 v9; 
  _ADAPTER_OBJECT *v11; 
  _ADAPTER_OBJECT *AdjustedClientToken; 
  _ETHREAD *CurrentThread; 
  char v14; 
  bool v15; 
  _ETHREAD *v16; 
  _EX_FAST_REF *p_Token; 
  VOID *v18; 
  _SECURITY_IMPERSONATION_LEVEL v19; 
  UINT8 v20; 
  char v21; 
  _ETHREAD *v22; 
  unsigned __int64 v23; 
  char v24; 
  VOID **DuplicateToken; 
  VOID *v27; 
  UINT8 v28; 
  int v29; 
  _SECURITY_IMPERSONATION_LEVEL v30; 
  _EX_PUSH_LOCK *p_ProcessLock; 
  char UseProcessTrust; 
  _KTHREAD *Threada; 

  Process = Thread->Tcb.Process;
  v6 = 0;
  UseProcessTrust = 0;
  v9 = (unsigned __int64)Token;
  if( !Token )
  {
    v11 = 0i64;
    AdjustedClientToken = 0i64;
    if( (Thread->CrossThreadFlags & 8) == 0 )
      return 0;
    CurrentThread = (_ETHREAD *)KeGetCurrentThread();
    --CurrentThread->Tcb.KernelApcDisable;
    ExAcquirePushLockExclusiveEx(&Thread->ThreadLock, 0i64);
    if( (Thread->CrossThreadFlags & 8) != 0 )
    {
      AdjustedClientToken = (_ADAPTER_OBJECT *)Thread->AdjustedClientToken;
      v11 = (_ADAPTER_OBJECT *)(Thread->ClientSecurity.ImpersonationData & 0xFFFFFFFFFFFFFFF8ui64);
      Thread->AdjustedClientToken = 0i64;
      _InterlockedAnd((volatile signed __int32 *)&Thread->1296, 0xFFFFFFF7);
    }
    v14 = _InterlockedExchangeAdd64(&Thread->ThreadLock._bf_0, 0xFFFFFFFFFFFFFFFFui64);
    if( (v14 & 2) != 0 && (v14 & 4) == 0 )
      ExfTryToWakePushLock(&Thread->ThreadLock);
    KeAbPostRelease(&Thread->ThreadLock);
    v15 = CurrentThread->Tcb.KernelApcDisable++ == -1;
    if( v15
      && ($F25F8C4BA33AF922A5F1AF68CD89DDDF *)CurrentThread->Tcb.ApcState.ApcListHead[0].Flink != &CurrentThread->Tcb.152
      && !CurrentThread->Tcb.SpecialApcDisable )
    {
      KiCheckForKernelApcDelivery();
    }
    v16 = CurrentThread;
LABEL_21:
    PspWriteTebImpersonationInfo(Thread, v16);
    if( v11 )
      HalPutDmaAdapter(v11);
    if( AdjustedClientToken )
      HalPutDmaAdapter(AdjustedClientToken);
    return 0;
  }
  p_Token = &Process->Token;
  v18 = ObFastReferenceObject(&Process->Token);
  if( !v18 )
  {
    Threada = (_ETHREAD *)KeGetCurrentThread();
    --Threada->Tcb.KernelApcDisable;
    p_ProcessLock = &Process->ProcessLock;
    ExAcquirePushLockSharedEx(p_ProcessLock, 0i64);
    v18 = ObFastReferenceObjectLocked(p_Token);
    if( _InterlockedCompareExchange64(&p_ProcessLock->_bf_0, 0i64, 17i64) != 17 )
      ExfReleasePushLockShared(p_ProcessLock);
    KeAbPostRelease(p_ProcessLock);
    KeLeaveCriticalRegionThread(&Threada->Tcb);
    if( !v18 )
    {
      v21 = ImpersonationLevel;
      goto LABEL_13;
    }
  }
  v19 = ImpersonationLevel;
  LODWORD(Threada) = ImpersonationLevel;
  if( SeTokenCanImpersonate(v18, (VOID *)v9, ImpersonationLevel, (UINT8 *)&UseProcessTrust) < 0 )
  {
    v15 = *(_DWORD *)(v9 + 192) == 2;
    v30 = SecurityIdentification;
    LODWORD(Threada) = 1;
    if( v15 && *(int *)(v9 + 196) < 1 )
    {
      v30 = *(_DWORD *)(v9 + 196);
      LODWORD(Threada) = v30;
    }
    v29 = SeCopyClientToken((VOID *)v9, v30, v20, 0i64, 0i64);
    if( v29 >= 0 )
    {
      v9 = 0i64;
      v6 = 1;
      goto LABEL_12;
    }
  }
  else
  {
    if( !UseProcessTrust )
      goto LABEL_12;
    DuplicateToken = (VOID **)SeQueryTokenTrustSid(v18);
    LOBYTE(v27) = 1;
    v29 = SeCopyClientToken((VOID *)v9, v19, v28, v27, DuplicateToken);
    if( v29 >= 0 )
    {
      if( CopyOnOpen )
      {
        SeSetTokenTrustLink(0i64, (VOID *)v9);
      }
      else
      {
        v9 = 0i64;
        v6 = 1;
      }
LABEL_12:
      ObFastDereferenceObject(p_Token, v18);
      v15 = v6 == 0;
      v21 = (char)Threada;
      if( !v15 )
      {
LABEL_14:
        v22 = (_ETHREAD *)KeGetCurrentThread();
        v23 = v9 & 0xFFFFFFFFFFFFFFF8ui64 | v21 & 3 | (4i64 * EffectiveOnly);
        --v22->Tcb.KernelApcDisable;
        ExAcquirePushLockExclusiveEx(&Thread->ThreadLock, 0i64);
        if( (Thread->CrossThreadFlags & 8) != 0 )
        {
          AdjustedClientToken = (_ADAPTER_OBJECT *)Thread->AdjustedClientToken;
          v11 = (_ADAPTER_OBJECT *)(Thread->ClientSecurity.ImpersonationData & 0xFFFFFFFFFFFFFFF8ui64);
        }
        else
        {
          v11 = 0i64;
          AdjustedClientToken = 0i64;
          _InterlockedOr((volatile signed __int32 *)&Thread->1296, 8u);
        }
        Thread->AdjustedClientToken = 0i64;
        Thread->ClientSecurity.ImpersonationData = v23;
        if( CopyOnOpen )
          _InterlockedOr((volatile signed __int32 *)&Thread->1296, 0x100u);
        else
          _InterlockedAnd((volatile signed __int32 *)&Thread->1296, 0xFFFFFEFF);
        v24 = _InterlockedExchangeAdd64(&Thread->ThreadLock._bf_0, 0xFFFFFFFFFFFFFFFFui64);
        if( (v24 & 2) != 0 && (v24 & 4) == 0 )
          ExfTryToWakePushLock(&Thread->ThreadLock);
        KeAbPostRelease(&Thread->ThreadLock);
        v15 = v22->Tcb.KernelApcDisable++ == -1;
        if( v15
          && ($F25F8C4BA33AF922A5F1AF68CD89DDDF *)v22->Tcb.ApcState.ApcListHead[0].Flink != &v22->Tcb.152
          && !v22->Tcb.SpecialApcDisable )
        {
          KiCheckForKernelApcDelivery();
        }
        v16 = v22;
        goto LABEL_21;
      }
LABEL_13:
      ObfReferenceObject((PVOID)v9);
      goto LABEL_14;
    }
  }
  ObFastDereferenceObject(p_Token, v18);
  return v29;
}

Referenced by:

AlpcpImpersonateMessage
CmpCmdHiveOpen
CmpOpenHiveFile
NtImpersonateAnonymousToken
PsAssignImpersonationToken
PsRevertThreadToSelf
PsRevertToSelf
SeImpersonateClientEx