KiDetachProcess

VOID __stdcall KiDetachProcess(_KAPC_STATE *ApcState, UINT64 Force){
  __int64 v2; 
  _ETHREAD *CurrentThread; 
  unsigned __int64 v4; 
  char v5; 
  volatile signed __int32 *Process; 
  int v8; 
  struct _KPRCB *CurrentPrcb; 
  $F25F8C4BA33AF922A5F1AF68CD89DDDF *v10; 
  $A184FAFDEBB902F1E6D1F235B14D565F *v11; 
  _LIST_ENTRY *Flink; 
  _LIST_ENTRY *v13; 
  _LIST_ENTRY *v14; 
  struct _KPRCB *v15; 
  unsigned __int64 v16; 
  _EPROCESS *v17; 
  unsigned __int64 v18; 
  __int64 v19; 
  unsigned __int64 DirectoryTableBase; 
  unsigned __int64 v21; 
  char v22; 
  unsigned __int8 v23; 
  unsigned __int32 v24; 
  unsigned __int32 v25; 
  signed __int64 *v26; 
  signed __int64 v27; 
  _LIST_ENTRY *Blink; 
  _LIST_ENTRY *v29; 
  _DWORD *SchedulerAssist; 
  unsigned __int8 v31; 
  struct _KPRCB *v32; 
  _DWORD *v33; 
  int v34; 
  unsigned __int64 v35; 
  UINT64 SpinCount; 
  UINT64 v37; 
  __int64 CurrentIrql; 

  CurrentThread = (_ETHREAD *)KeGetCurrentThread();
  v4 = 2i64;
  v5 = Force;
  Process = (volatile signed __int32 *)CurrentThread->Tcb.ApcState.Process;
  v8 = Force & 2;
  if( (Force & 2) != 0 )
  {
    LOBYTE(v2) = 15;
    CurrentIrql = v2;
  }
  else
  {
    CurrentIrql = KeGetCurrentIrql();
    __writecr8(2ui64);
    CurrentPrcb = KeGetCurrentPrcb();
    LODWORD(SpinCount) = 0;
    while( _interlockedbittestandset64((volatile signed __int32 *)&CurrentThread->Tcb.ThreadLock, 0i64) )
    {
      do
        KeYieldProcessorEx(&SpinCount);
      while( CurrentThread->Tcb.ThreadLock );
      SchedulerAssist = CurrentPrcb->SchedulerAssist;
      if( SchedulerAssist && CurrentPrcb->NestingLevel <= 1u )
        ++SchedulerAssist[6];
    }
    LOBYTE(v2) = CurrentIrql;
    v4 = 2i64;
  }
  if( CurrentThread->Tcb.ApcState.KernelApcPending )
  {
    do
    {
      if( CurrentThread->Tcb.SpecialApcDisable || (_BYTE)v2 )
        break;
      KiReleaseThreadLockSafe((INT64)CurrentThread);
      __writecr8((unsigned __int8)CurrentIrql);
      v31 = KeGetCurrentIrql();
      __writecr8(2ui64);
      CurrentIrql = v31;
      v32 = KeGetCurrentPrcb();
      LODWORD(v37) = 0;
      while( _interlockedbittestandset64((volatile signed __int32 *)&CurrentThread->Tcb.ThreadLock, 0i64) )
      {
        do
          KeYieldProcessorEx(&v37);
        while( CurrentThread->Tcb.ThreadLock );
        v33 = v32->SchedulerAssist;
        if( v33 && v32->NestingLevel <= 1u )
        {
          v34 = v33[6] + 1;
          v33[6] = v34;
        }
      }
      LOBYTE(v2) = CurrentIrql;
    }
    while( CurrentThread->Tcb.ApcState.KernelApcPending );
    v4 = 2i64;
  }
  if( !CurrentThread->Tcb.ApcStateIndex
    || (CurrentThread->Tcb.ApcState.InProgressFlags & 1) != 0
    || (v10 = &CurrentThread->Tcb.152, ($F25F8C4BA33AF922A5F1AF68CD89DDDF *)v10->ApcState.ApcListHead[0].Flink != v10)
    || (unsigned __int8 *)CurrentThread->Tcb.ApcState.ApcListHead[1].Flink != &CurrentThread->Tcb.ApcStateFill[16] )
  {
    KeBugCheck(6u);
  }
  CurrentThread->Tcb._bf_0 |= 0x800u;
  v11 = &CurrentThread->Tcb.600;
  if( ApcState == (_KAPC_STATE *)&CurrentThread->Tcb.600 )
  {
    CurrentThread->Tcb.ApcState.Process = CurrentThread->Tcb.SavedApcState.Process;
    CurrentThread->Tcb.ApcState.InProgressFlags = CurrentThread->Tcb.SavedApcState.InProgressFlags;
    CurrentThread->Tcb.ApcState.KernelApcPending = CurrentThread->Tcb.SavedApcState.KernelApcPending;
    CurrentThread->Tcb.ApcState.UserApcPendingAll = CurrentThread->Tcb.SavedApcState.UserApcPendingAll;
    Flink = v11->SavedApcState.ApcListHead[0].Flink;
    if( ($A184FAFDEBB902F1E6D1F235B14D565F *)v11->SavedApcState.ApcListHead[0].Flink == v11 )
    {
      CurrentThread->Tcb.ApcState.ApcListHead[0].Blink = CurrentThread->Tcb.ApcState.ApcListHead;
      v10->ApcState.ApcListHead[0].Flink = (_LIST_ENTRY *)v10;
      CurrentThread->Tcb.ApcState.KernelApcPending = 0;
    }
    else
    {
      Blink = CurrentThread->Tcb.SavedApcState.ApcListHead[0].Blink;
      v10->ApcState.ApcListHead[0].Flink = Flink;
      CurrentThread->Tcb.ApcState.ApcListHead[0].Blink = Blink;
      Flink->Blink = (_LIST_ENTRY *)v10;
      Blink->Flink = (_LIST_ENTRY *)v10;
    }
    v13 = CurrentThread->Tcb.SavedApcState.ApcListHead[1].Flink;
    v14 = &CurrentThread->Tcb.ApcState.ApcListHead[1];
    if( v13 == (_LIST_ENTRY *)&CurrentThread->Tcb.SavedApcStateFill[16] )
    {
      CurrentThread->Tcb.ApcState.ApcListHead[1].Blink = &CurrentThread->Tcb.ApcState.ApcListHead[1];
      v14->Flink = v14;
      CurrentThread->Tcb.ApcState.UserApcPendingAll = 0;
    }
    else
    {
      v29 = CurrentThread->Tcb.SavedApcState.ApcListHead[1].Blink;
      v14->Flink = v13;
      CurrentThread->Tcb.ApcState.ApcListHead[1].Blink = v29;
      v13->Blink = v14;
      v29->Flink = v14;
    }
    CurrentThread->Tcb.SavedApcState.Process = 0i64;
    CurrentThread->Tcb.ApcStateIndex = 0;
  }
  else
  {
    KiMoveApcState(ApcState, &CurrentThread->Tcb.ApcState);
  }
  if( !v8 )
  {
    CurrentThread->Tcb.ThreadLock = 0i64;
    v15 = KeGetCurrentPrcb();
    if( v15->SchedulerAssist )
    {
      if( v15->NestingLevel <= 1u && !(_DWORD)v14 )
      {
        LOBYTE(v2) = CurrentIrql;
        v4 = 2i64;
      }
    }
  }
  v16 = (unsigned __int64)KeGetCurrentPrcb();
  v17 = CurrentThread->Tcb.ApcState.Process;
  v18 = *(unsigned __int8 *)(v16 + 209);
  v19 = 8i64 * *(unsigned __int8 *)(v16 + 208) + 376;
  _interlockedbittestandset64((volatile signed __int32 *)&v17->Pcb.gap0[v19], v18);
  DirectoryTableBase = v17->Pcb.DirectoryTableBase;
  if( KiKvaShadow )
  {
    v21 = v17->Pcb.DirectoryTableBase;
    if( (DirectoryTableBase & 2) != 0 )
      v21 = DirectoryTableBase | 0x8000000000000000ui64;
    __writegsqword(0x9000u, v21);
    KiSetAddressPolicy(v17->Pcb.AddressPolicy);
    LOBYTE(v2) = CurrentIrql;
    v4 = 2i64;
  }
  __writecr3(DirectoryTableBase);
  if( !KiFlushPcid && KiKvaShadow )
  {
    v16 = __readcr4();
    if( (v16 & 0x20080) != 0 )
    {
      __writecr4(v16 ^ 0x80);
      __writecr4(v16);
    }
    else
    {
      v35 = __readcr3();
      __writecr3(v35);
    }
  }
  _interlockedbittestandreset64((volatile signed __int32 *)((char *)Process + v19), v18);
  CurrentThread->Tcb._bf_0 &= ~0x800u;
  if( !v8 )
    __writecr8((unsigned __int8)v2);
  if( (v5 & 1) == 0 && (_InterlockedExchangeAdd(Process + 210, 0xFFFFFFF8) & 0xFFFFFFF8) == 8 )
  {
    v22 = 0;
    v23 = KeGetCurrentIrql();
    __writecr8(v4);
    KiAcquireKobjectLockSafe((VOID *)Process);
    v24 = *((_DWORD *)Process + 210);
    if( (v24 & 7) == 0 )
    {
      v16 = (unsigned __int64)(Process + 12);
      if( *(_QWORD *)v16 != v16 && v24 < 8 )
      {
        while( 1 )
        {
          v16 = v24 & 0xFFFFFFF8 | 3;
          v25 = v24;
          v24 = _InterlockedCompareExchange(Process + 210, v16, v24);
          if( v25 == v24 )
            break;
          if( v24 >= 8 )
            goto LABEL_36;
        }
        v22 = 1;
      }
    }
LABEL_36:
    _InterlockedAnd(Process, 0xFFFFFF7F);
    if( v22 )
    {
      v26 = (signed __int64 *)(Process + 90);
      _m_prefetchw(&KiProcessOutSwapListHead);
      v27 = KiProcessOutSwapListHead;
      do
      {
        *v26 = v27;
        v16 = v27;
        v27 = _InterlockedCompareExchange64(&KiProcessOutSwapListHead, (signed __int64)v26, v27);
      }
      while( v27 != v16 );
      if( !v27 )
        KeSetEvent((PRKEVENT)&KiSwapEvent, 10, 0);
    }
    __writecr8(v23);
  }
  if( ($F25F8C4BA33AF922A5F1AF68CD89DDDF *)v10->ApcState.ApcListHead[0].Flink != v10 )
  {
    LOBYTE(v16) = 1;
    CurrentThread->Tcb.ApcState.KernelApcPending = 1;
    HalRequestSoftwareInterrupt(v16);
  }
}

Referenced by:

KeDetachProcess
KeUnstackDetachProcess
KiUnstackDetachProcess
MiTrimOrAgeWorkingSet