PsImpersonateContainerOfThread

BOOLEAN __fastcall PsImpersonateContainerOfThread(__int64 a1){
  _ETHREAD *CurrentThread; 
  UINT8 CurrentIrql; 
  int v4; 
  unsigned __int8 v5; 
  struct _KPRCB *CurrentPrcb; 
  char v7; 
  struct _KPRCB *v8; 
  EVENT_DESCRIPTOR *v9; 
  __int64 v10; 
  _KSCHEDULING_GROUP *v11; 
  UINT64 v12; 
  BOOLEAN result; 
  __int64 v14; 
  ULONG_PTR v15; 
  struct _KPRCB *v16; 
  __int64 v18; 
  int v19; 
  __int64 v20; 
  __int64 v21; 
  __int16 v22; 
  bool v23; 
  INT64 v24; 
  unsigned int v25; 
  INT64 v26; 
  INT64 v27; 
  unsigned int v28; 
  unsigned int v29; 
  UINT64 UserDataCount; 
  UINT64 SpinCount; 
  int v32; 
  int v33; 
  _SINGLE_LIST_ENTRY ReadyList; 
  EVENT_DATA_DESCRIPTOR UserData; 
  int *v36; 
  __int64 v37; 
  int v38; 
  if( ObpTraceFlags )
    ObpPushStackInfo(a1 - 48, 1, 1i64, 1953394499i64);
  ObpIncrPointerCount((volatile INT64 *)(a1 - 48));
  CurrentThread = (_ETHREAD *)KeGetCurrentThread();
  PspRevertContainerImpersonation((ULONG_PTR)CurrentThread);
  CurrentIrql = KeGetCurrentIrql();
  __writecr8(2ui64);
  ExpAcquireSpinLockExclusive((INT64 *)PspThreadWorkOnBehalfLock, CurrentIrql);
  *((_QWORD *)CurrentThread + 184) = a1;
  v4 = *(char *)(a1 + 195);
  if( v4 > 15 )
    LOBYTE(v4) = 15;
  ReadyList.Next = 0i64;
  v5 = KeGetCurrentIrql();
  __writecr8(2ui64);
  CurrentPrcb = KeGetCurrentPrcb();
  LODWORD(SpinCount) = 0;
  while( _interlockedbittestandset64((volatile signed __int32 *)CurrentThread + 16, 0i64) )
  {
    do
      KeYieldProcessorEx(&SpinCount);
    while( *((_QWORD *)CurrentThread + 8) );
    v14 = *((_QWORD *)CurrentPrcb + 4247);
    if( v14 && *((_BYTE *)CurrentPrcb + 32) <= 1u )
      ++*(_DWORD *)(v14 + 24);
  }
  *((_BYTE *)CurrentThread + 795) = v4;
  v7 = *((_BYTE *)CurrentThread + (char)v4 + 824);
  if( v7 == -1 )
    KeBugCheckEx(0x157u, (ULONG_PTR)CurrentThread, (char)v4, 1ui64, 0i64);
  *((_BYTE *)CurrentThread + (char)v4 + 824) = v7 + 1;
  *((_DWORD *)CurrentThread + 214) |= 1 << v4;
  if( *((char *)CurrentThread + 195) < (char)v4 )
    KiSetPriorityThread((_KTHREAD *)CurrentThread, &ReadyList, (unsigned int)(char)v4);
  KiReleaseThreadLockSafe((INT64)CurrentThread);
  v8 = KeGetCurrentPrcb();
  KiReadyDeferredReadyList(v8, &ReadyList);
  if( v5 < 2u )
  {
    v15 = *((_QWORD *)v8 + 1);
    if( *((_QWORD *)v8 + 2) )
    {
      KiAbProcessContextSwitch(*((_KTHREAD **)v8 + 1), 0i64);
      v16 = KeGetCurrentPrcb();
      HIDWORD(SpinCount) = 0;
      while( _interlockedbittestandset64((volatile signed __int32 *)v8 + 12, 0i64) )
      {
        do
          KeYieldProcessorEx((UINT64 *)((char *)&SpinCount + 4));
        while( *((_QWORD *)v8 + 6) );
        v18 = *((_QWORD *)v16 + 4247);
        if( v18 && *((_BYTE *)v16 + 32) <= 1u )
        {
          v19 = *(_DWORD *)(v18 + 24) + 1;
          *(_DWORD *)(v18 + 24) = v19;
        }
      }
      v20 = *((_QWORD *)v8 + 2);
      *((_QWORD *)v8 + 2) = 0i64;
      _disable();
      KiEndThreadCycleAccumulation(v8, (_KTHREAD *)v15, 0i64);
      _enable();
      *((_QWORD *)v8 + 1) = v20;
      if( *(_BYTE *)(v20 + 388) == 1 )
      {
        v21 = (unsigned int)(*(_DWORD *)(v20 + 132) - *(_DWORD *)(v20 + 436));
        *(_DWORD *)(v20 + 132) = v21 + KUSER_SHARED_DATA.TickCount.LowPart;
      }
      *(_BYTE *)(v20 + 388) = 2;
      *(_BYTE *)(v15 + 643) = 32;
      *(_BYTE *)(v15 + 390) = v5;
      KiQueueReadyThread((__int64)v8, v15, v21);
      if( !KiSwapContext((PKTHREAD)v15, (PKTHREAD)v20) )
        goto LABEL_37;
    }
    else if( (*(_DWORD *)(v15 + 116) & 0x40) == 0 )
    {
      goto LABEL_37;
    }
    __writecr8(1ui64);
    *(_DWORD *)(v15 + 116) &= ~0x40u;
    KiDeliverApc(0, 0i64, 0i64);
LABEL_37:
    __writecr8(v5);
    goto LABEL_12;
  }
  if( *((_QWORD *)v8 + 2) && !*((_BYTE *)v8 + 12586) )
    KiRequestSoftwareInterrupt(v8, 2);
LABEL_12:
  if( KeHeteroSystemQos )
  {
    v22 = v38;
    _disable();
    v23 = (v22 & 0x200) != 0;
    v24 = (unsigned __int8)*(_DWORD *)(a1 + 512);
    v25 = (unsigned __int8)*((_DWORD *)CurrentThread + 128);
    if( (_DWORD)v24 != v25 && ((_DWORD)v24 == 3 || v25 == 3 || (unsigned int)v24 < v25) )
    {
      KeSetThreadBamQosLevel((INT64)CurrentThread, v24);
      v28 = (unsigned __int8)*(_DWORD *)(v27 + 236);
      v29 = (unsigned __int8)*((_DWORD *)CurrentThread + 128);
      if( v29 != v28 && (v29 == 3 || v28 == 3 || v29 < v28) )
        KeCheckAndApplyBamQos(v27, (INT64)CurrentThread, v26, v27);
    }
    if( v23 )
      _enable();
  }
  ExReleaseSpinLockExclusiveFromDpcLevel((INT64 *)PspThreadWorkOnBehalfLock);
  __writecr8(CurrentIrql);
  v10 = *(_QWORD *)(*(_QWORD *)(a1 + 544) + 1296i64);
  if( v10 )
  {
    v11 = *(_KSCHEDULING_GROUP **)(v10 + 1016);
    if( v11 )
      KeSetThreadChargeOnlySchedulingGroup((_KTHREAD *)CurrentThread, v11);
  }
  v12 = *(_QWORD *)EtwpPsProvRegHandle;
  result = EtwEventEnabled(*(UINT64 *)EtwpPsProvRegHandle, (EVENT_DESCRIPTOR *)&ThreadWorkOnBehalfUpdate, v9);
  if( result )
  {
    v32 = 0;
    UserData.Ptr = (unsigned __int64)&v32;
    v33 = *(_DWORD *)(a1 + 1152);
    *(_QWORD *)&UserData.Size = 4i64;
    v36 = &v33;
    v37 = 4i64;
    LODWORD(UserDataCount) = 2;
    return EtwWriteEx(
             v12,
             (EVENT_DESCRIPTOR *)&ThreadWorkOnBehalfUpdate,
             0i64,
             1ui64,
             0i64,
             0i64,
             UserDataCount,
             &UserData);
  }
  return result;
}

Referenced by:

IopProcessWorkItem
NtAlpcImpersonateClientContainerOfPort
NtSetInformationThread