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