PsCallEnclave

int __fastcall PsCallEnclave(UINT64 a1, INT64 a2, NTSTATUS a3, INT64 *a4){
  _ETHREAD *CurrentThread; 
  int result; 
  __int64 v7; 
  INT64 Process; 
  UINT64 v9; 
  __int64 v10; 
  int EnclaveReturnFrame; 
  _KTRAP_FRAME *BaseTrapFrame; 
  __int64 v13; 
  __int64 v14; 
  _EX_PUSH_LOCK *v15; 
  __int64 v16; 
  NTSTATUS v17; 
  PVOID v18; 
  int v19; 
  int v20; 
  PVOID v21; 
  unsigned int v22; 
  NTSTATUS v23; 
  INT64 v24; 
  INT64 v25; 
  UINT64 v26; 
  INT64 v27; 
  int v28; 
  _RTL_BALANCED_NODE *v29; 
  BOOL v30; 
  _RTL_BALANCED_NODE *v31; 
  UINT64 v33; 
  char v34; 
  char v35; 
  INT64 v36; 
  int v37; 
  INT64 v38; 
  int v39; 
  PVOID P; 
  INT64 v41; 
  INT64 v42; 
  _RTL_BALANCED_NODE **Tree; 
  __int64 v44; 
  INT64 v45; 
  _QWORD v46[10]; 
  UINT64 v47; 
  INT64 v48; 
  NTSTATUS ExitStatus; 
  INT64 *v50; 

  v50 = a4;
  ExitStatus = a3;
  v48 = a2;
  v47 = a1;
  v38 = 0i64;
  v36 = 0i64;
  v41 = 0i64;
  v42 = 0i64;
  v34 = 0;
  v46[0] = 0i64;
  CurrentThread = (_ETHREAD *)KeGetCurrentThread();
  v46[1] = CurrentThread;
  v45 = 0i64;
  if( CurrentThread->Tcb.PreviousMode != 1 )
    return -1073741585;
  if( v47 )
  {
    if( a2 )
      return -1073741584;
  }
  else if( a2 )
  {
    goto LABEL_9;
  }
  if( (ExitStatus & 0xFFFFFFFE) != 0 )
    return -1073741583;
LABEL_9:
  v7 = 0x7FFFFFFF0000i64;
  if( (unsigned __int64)a4 < 0x7FFFFFFF0000i64 )
    v7 = (__int64)a4;
  *(_QWORD *)v7 = *(_QWORD *)v7;
  v38 = *a4;
  Process = (INT64)CurrentThread->Tcb.ApcState.Process;
  if( a2 )
  {
    result = PspSelectVsmEnclaveByNumber(Process, a2, &v36);
    v9 = v47;
  }
  else
  {
    v9 = v47;
    result = MmSelectVsmEnclaveByAddress(Process, v47, &v36);
  }
  if( result < 0 )
    return result;
  v10 = v36;
  if( !*(_DWORD *)(v36 + 40) )
  {
    EnclaveReturnFrame = -1073741816;
    goto LABEL_93;
  }
  if( *(_BYTE *)(v36 + 76) )
  {
    --CurrentThread->Tcb.KernelApcDisable;
    v15 = (_EX_PUSH_LOCK *)(v10 + 112);
    ExAcquirePushLockExclusiveEx((_EX_PUSH_LOCK *)(v10 + 112), 0i64);
    Tree = (_RTL_BALANCED_NODE **)(v10 + 104);
    v16 = *(_QWORD *)(v10 + 104);
    while( v16 )
    {
      v23 = MiHotPatchImageTreeCompare(v9, v16);
      if( v23 >= 0 )
      {
        if( v23 <= 0 )
          break;
        v16 = *(_QWORD *)(v16 + 8);
      }
      else
      {
        v16 = *(_QWORD *)v16;
      }
    }
    if( (_InterlockedExchangeAdd64(&v15->_bf_0, 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
      ExfTryToWakePushLock((_EX_PUSH_LOCK *)(v10 + 112));
    KeAbPostRelease((VOID *)(v10 + 112));
    KeLeaveCriticalRegionThread(&CurrentThread->Tcb);
    if( !v16 )
    {
      EnclaveReturnFrame = -1073741800;
      goto LABEL_92;
    }
    v44 = v16;
    goto LABEL_61;
  }
  BaseTrapFrame = PsGetBaseTrapFrame(CurrentThread);
  v45 = (INT64)BaseTrapFrame;
  --CurrentThread->Tcb.SpecialApcDisable;
  EnclaveReturnFrame = RtlPrepareEnclaveCall(
                         (__int64)BaseTrapFrame,
                         (__int64)a4,
                         v13,
                         v14,
                         (CurrentThread->Tcb._bf_0 & 0x100000) != 0,
                         &v42,
                         &v41);
  KiLeaveGuardedRegionUnsafe((__int64)CurrentThread);
  if( EnclaveReturnFrame < 0 )
    goto LABEL_93;
  --CurrentThread->Tcb.KernelApcDisable;
  v15 = (_EX_PUSH_LOCK *)(v10 + 112);
  ExAcquirePushLockExclusiveEx((_EX_PUSH_LOCK *)(v10 + 112), 0i64);
  Tree = (_RTL_BALANCED_NODE **)(v10 + 104);
  v16 = *(_QWORD *)(v10 + 104);
  while( v16 )
  {
    v17 = MiHotPatchImageTreeCompare((UINT64)CurrentThread, v16);
    if( v17 >= 0 )
    {
      if( v17 <= 0 )
        break;
      v16 = *(_QWORD *)(v16 + 8);
    }
    else
    {
      v16 = *(_QWORD *)v16;
    }
  }
  if( !v16 )
  {
    v18 = 0i64;
    P = 0i64;
    if( v48 )
    {
      EnclaveReturnFrame = -1073741584;
    }
    else
    {
      v19 = *(_DWORD *)(v10 + 72);
      if( v19 )
      {
        *(_DWORD *)(v10 + 72) = v19 - 1;
        EnclaveReturnFrame = 0;
      }
      else
      {
        PspPrepareEnclaveThreadWait();
        EnclaveReturnFrame = v20;
        v18 = P;
      }
      if( EnclaveReturnFrame >= 0 && !v18 )
      {
LABEL_45:
        v16 = *(_QWORD *)(v10 + 128);
        *(_QWORD *)(v10 + 128) = *(_QWORD *)v16;
        *(_QWORD *)(v16 + 24) = CurrentThread;
        *(_QWORD *)(v16 + 32) = 0i64;
        goto LABEL_46;
      }
    }
    if( (_InterlockedExchangeAdd64(&v15->_bf_0, 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
      ExfTryToWakePushLock((_EX_PUSH_LOCK *)(v10 + 112));
    KeAbPostRelease((VOID *)(v10 + 112));
    KeLeaveCriticalRegionThread(&CurrentThread->Tcb);
    if( EnclaveReturnFrame < 0 )
    {
LABEL_92:
      v10 = v36;
      goto LABEL_93;
    }
    v21 = P;
    v22 = KeWaitForSingleObject((UINT64)P + 16, 0, 1, 0, (unsigned __int64)v46 & -(__int64)((ExitStatus & 1) != 0));
    v10 = v36;
    if( v22 )
      EnclaveReturnFrame = PspRemoveEnclaveThreadWait(v36, (INT64 *)v21, v22);
    else
      EnclaveReturnFrame = *((_DWORD *)v21 + 10);
    ExFreePoolWithTag(v21, 0);
    if( EnclaveReturnFrame )
    {
      if( (unsigned int)(EnclaveReturnFrame - 257) > 1
        && EnclaveReturnFrame != -1073740526
        && EnclaveReturnFrame != 192 )
      {
        EnclaveReturnFrame = -1073741749;
      }
      goto LABEL_93;
    }
    --CurrentThread->Tcb.KernelApcDisable;
    ExAcquirePushLockExclusiveEx(v15, 0i64);
    goto LABEL_45;
  }
LABEL_46:
  v44 = v16;
  if( (_InterlockedExchangeAdd64(&v15->_bf_0, 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
    ExfTryToWakePushLock(v15);
  KeAbPostRelease(v15);
  KeLeaveCriticalRegionThread(&CurrentThread->Tcb);
  if( *(_DWORD *)(v16 + 36) == -1 )
  {
    EnclaveReturnFrame = -1073741670;
    goto LABEL_92;
  }
LABEL_61:
  --CurrentThread->Tcb.SpecialApcDisable;
  CurrentThread->SameThreadPassiveFlags |= 0x200u;
  v37 = *(_DWORD *)(v16 + 32);
  v10 = v36;
  EnclaveReturnFrame = VslCallEnclave(v36, &v37, (__int64 *)&v47, ExitStatus, &v38, &v42, &v41, &ExitStatus, &v34);
  v39 = EnclaveReturnFrame;
  CurrentThread->SameThreadPassiveFlags &= ~0x200u;
  KiLeaveGuardedRegionUnsafe((__int64)CurrentThread);
  if( v34 )
    ZwTerminateProcess((VOID *)0xFFFFFFFFFFFFFFFFi64, ExitStatus);
  if( EnclaveReturnFrame < 0 )
  {
    if( !v48 )
      goto LABEL_87;
    v26 = v47;
    if( v48 )
      v26 = 0i64;
    v47 = v26;
  }
  v27 = v47;
  if( !v47 )
  {
    *v50 = v38;
    if( v48 )
    {
      if( (*(_DWORD *)(v16 + 36))-- == 1 )
      {
        --CurrentThread->Tcb.KernelApcDisable;
        ExAcquirePushLockExclusiveEx((_EX_PUSH_LOCK *)(v10 + 112), 0i64);
        RtlAvlRemoveNode((UINT64 *)(v10 + 104), (INT64 *)v16);
        if( (_InterlockedExchangeAdd64((volatile signed __int64 *)(v10 + 112), 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
          ExfTryToWakePushLock((_EX_PUSH_LOCK *)(v10 + 112));
        KeAbPostRelease((VOID *)(v10 + 112));
        KeLeaveCriticalRegionThread(&CurrentThread->Tcb);
        v10 = v36;
      }
    }
    goto LABEL_87;
  }
  --CurrentThread->Tcb.SpecialApcDisable;
  LODWORD(v33) = ExitStatus;
  EnclaveReturnFrame = RtlCreateEnclaveReturnFrame(
                         v45,
                         v24,
                         v25,
                         *(_QWORD *)(v10 + 8),
                         v27,
                         v33,
                         v42,
                         v41,
                         v38,
                         (CurrentThread->Tcb._bf_0 & 0x100000) != 0);
  KiLeaveGuardedRegionUnsafe((__int64)CurrentThread);
  if( v48 )
    goto LABEL_87;
  v28 = *(_DWORD *)(v16 + 36);
  if( v28 )
    goto LABEL_81;
  *(_DWORD *)(v16 + 32) = v37;
  --CurrentThread->Tcb.KernelApcDisable;
  ExAcquirePushLockExclusiveEx(v15, 0i64);
  v29 = *Tree;
  v30 = 0;
  v35 = 0;
  if( !v29 )
    goto LABEL_78;
  while( MiHotPatchImageTreeCompare((UINT64)CurrentThread, (INT64)v29) >= 0 )
  {
    v31 = v29->Children[1];
    if( !v31 )
    {
      v30 = 1;
      v35 = 1;
      goto LABEL_78;
    }
LABEL_76:
    v29 = v31;
  }
  v31 = v29->Children[0];
  if( v29->Children[0] )
    goto LABEL_76;
  v30 = 0;
  v35 = 0;
LABEL_78:
  RtlAvlInsertNodeEx(Tree, (UINT64)v29, v30, (_RTL_BALANCED_NODE *)v16);
  if( (_InterlockedExchangeAdd64(&v15->_bf_0, 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
    ExfTryToWakePushLock(v15);
  KeAbPostRelease(v15);
  KeLeaveCriticalRegionThread(&CurrentThread->Tcb);
  v28 = *(_DWORD *)(v16 + 36);
  v10 = v36;
LABEL_81:
  *(_DWORD *)(v16 + 36) = v28 + 1;
LABEL_87:
  if( !*(_BYTE *)(v10 + 76) && !*(_DWORD *)(v16 + 36) )
  {
    --CurrentThread->Tcb.KernelApcDisable;
    ExAcquirePushLockExclusiveEx((_EX_PUSH_LOCK *)(v10 + 112), 0i64);
    *(_QWORD *)v16 = *(_QWORD *)(v10 + 128);
    *(_QWORD *)(v10 + 128) = v16;
    PspReleaseEnclaveThread(v10);
    if( (_InterlockedExchangeAdd64((volatile signed __int64 *)(v10 + 112), 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
      ExfTryToWakePushLock((_EX_PUSH_LOCK *)(v10 + 112));
    KeAbPostRelease((VOID *)(v10 + 112));
    KeLeaveCriticalRegionThread(&CurrentThread->Tcb);
    goto LABEL_92;
  }
LABEL_93:
  PsDereferenceVsmEnclave((PVOID)v10);
  return EnclaveReturnFrame;
}

Referenced by:

NtCallEnclave