PsCallEnclave
INT64 __fastcall PsCallEnclave(INT64 a1, INT64 a2, INT64 a3, INT64 *a4){
_ETHREAD *CurrentThread;
INT64 result;
__int64 v7;
INT64 v8;
UINT64 v9;
char *v10;
int EnclaveReturnFrame;
INT64 v12;
INT64 v13;
INT64 v14;
volatile signed __int64 *v15;
INT64 v16;
int v17;
PVOID v18;
int v19;
PVOID v20;
unsigned int v21;
int v22;
INT64 v23;
INT64 v24;
UINT64 v25;
INT64 v26;
int v27;
_QWORD *v28;
bool v29;
_QWORD *v30;
_QWORD *a6;
char a9;
char v34;
PVOID v35;
INT64 v36;
INT64 a5;
int v38;
PVOID P;
INT64 a7;
INT64 v41;
unsigned __int64 *v42;
INT64 v43;
INT64 v44;
_QWORD v45[10];
UINT64 a2a;
INT64 v47;
NTSTATUS ExitStatus;
INT64 *v49;
v49 = a4;
ExitStatus = a3;
v47 = a2;
a2a = a1;
a5 = 0i64;
v35 = 0i64;
a7 = 0i64;
v41 = 0i64;
a9 = 0;
v45[0] = 0i64;
CurrentThread = (_ETHREAD *)KeGetCurrentThread();
v45[1] = CurrentThread;
v44 = 0i64;
if( *((_BYTE *)CurrentThread + 562) != 1 )
return 3221225711i64;
if( a2a )
{
if( a2 )
return 3221225712i64;
}
else if( a2 )
{
goto LABEL_9;
}
if( (ExitStatus & 0xFFFFFFFE) != 0 )
return 3221225713i64;
LABEL_9:
v7 = 0x7FFFFFFF0000i64;
if( (unsigned __int64)a4 < 0x7FFFFFFF0000i64 )
v7 = (__int64)a4;
*(_QWORD *)v7 = *(_QWORD *)v7;
a5 = *a4;
v8 = *((_QWORD *)CurrentThread + 23);
if( a2 )
{
result = PspSelectVsmEnclaveByNumber(v8, a2, (INT64 *)&v35);
v9 = a2a;
}
else
{
v9 = a2a;
result = MmSelectVsmEnclaveByAddress(v8, a2a, &v35);
}
if( (int)result < 0 )
return result;
v10 = (char *)v35;
if( !*((_DWORD *)v35 + 10) )
{
EnclaveReturnFrame = -1073741816;
goto LABEL_93;
}
if( *((_BYTE *)v35 + 76) )
{
--*((_WORD *)CurrentThread + 242);
v15 = (volatile signed __int64 *)(v10 + 112);
ExAcquirePushLockExclusiveEx((UINT64)(v10 + 112), 0i64);
v42 = (unsigned __int64 *)(v10 + 104);
v16 = *((_QWORD *)v10 + 13);
while( v16 )
{
v22 = MiHotPatchImageTreeCompare(v9, v16);
if( v22 >= 0 )
{
if( v22 <= 0 )
break;
v16 = *(_QWORD *)(v16 + 8);
}
else
{
v16 = *(_QWORD *)v16;
}
}
if( (_InterlockedExchangeAdd64(v15, 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
ExfTryToWakePushLock((volatile INT64 *)v10 + 14);
KeAbPostRelease(v10 + 112);
KeLeaveCriticalRegionThread((__int64)CurrentThread);
if( !v16 )
{
EnclaveReturnFrame = -1073741800;
goto LABEL_92;
}
v43 = v16;
goto LABEL_61;
}
LODWORD(v12) = PsGetBaseTrapFrame((INT64)CurrentThread);
v44 = v12;
--*((_WORD *)CurrentThread + 243);
EnclaveReturnFrame = RtlPrepareEnclaveCall(
v12,
(INT64)a4,
v13,
v14,
(*((_DWORD *)CurrentThread + 29) & 0x100000) != 0,
&v41,
&a7);
KiLeaveGuardedRegionUnsafe((__int64)CurrentThread);
if( EnclaveReturnFrame < 0 )
goto LABEL_93;
--*((_WORD *)CurrentThread + 242);
v15 = (volatile signed __int64 *)(v10 + 112);
ExAcquirePushLockExclusiveEx((UINT64)(v10 + 112), 0i64);
v42 = (unsigned __int64 *)(v10 + 104);
v16 = *((_QWORD *)v10 + 13);
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( v47 )
{
EnclaveReturnFrame = -1073741584;
}
else
{
v19 = *((_DWORD *)v10 + 18);
if( v19 )
{
*((_DWORD *)v10 + 18) = v19 - 1;
EnclaveReturnFrame = 0;
}
else
{
EnclaveReturnFrame = PspPrepareEnclaveThreadWait((INT64)v10, &P);
v18 = P;
}
if( EnclaveReturnFrame >= 0 && !v18 )
{
LABEL_45:
v16 = *((_QWORD *)v10 + 16);
*((_QWORD *)v10 + 16) = *(_QWORD *)v16;
*(_QWORD *)(v16 + 24) = CurrentThread;
*(_QWORD *)(v16 + 32) = 0i64;
goto LABEL_46;
}
}
if( (_InterlockedExchangeAdd64(v15, 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
ExfTryToWakePushLock((volatile INT64 *)v10 + 14);
KeAbPostRelease(v10 + 112);
KeLeaveCriticalRegionThread((__int64)CurrentThread);
if( EnclaveReturnFrame < 0 )
{
LABEL_92:
v10 = (char *)v35;
goto LABEL_93;
}
v20 = P;
v21 = KeWaitForSingleObject(
(char *)P + 16,
Executive,
1,
0,
(PLARGE_INTEGER)((unsigned __int64)v45 & -(__int64)((ExitStatus & 1) != 0)));
v10 = (char *)v35;
if( v21 )
EnclaveReturnFrame = PspRemoveEnclaveThreadWait((INT64)v35, (INT64 *)v20, v21);
else
EnclaveReturnFrame = *((_DWORD *)v20 + 10);
ExFreePoolWithTag(v20, 0);
if( EnclaveReturnFrame )
{
if( (unsigned int)(EnclaveReturnFrame - 257) > 1
&& EnclaveReturnFrame != -1073740526
&& EnclaveReturnFrame != 192 )
{
EnclaveReturnFrame = -1073741749;
}
goto LABEL_93;
}
--*((_WORD *)CurrentThread + 242);
ExAcquirePushLockExclusiveEx((UINT64)v15, 0i64);
goto LABEL_45;
}
LABEL_46:
v43 = v16;
if( (_InterlockedExchangeAdd64(v15, 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
ExfTryToWakePushLock(v15);
KeAbPostRelease((PVOID)v15);
KeLeaveCriticalRegionThread((__int64)CurrentThread);
if( *(_DWORD *)(v16 + 36) == -1 )
{
EnclaveReturnFrame = -1073741670;
goto LABEL_92;
}
LABEL_61:
--*((_WORD *)CurrentThread + 243);
*((_DWORD *)CurrentThread + 325) |= 0x200u;
LODWORD(v36) = *(_DWORD *)(v16 + 32);
v10 = (char *)v35;
EnclaveReturnFrame = VslCallEnclave(
(INT64)v35,
&v36,
(INT64 *)&a2a,
(unsigned int)ExitStatus,
&a5,
&v41,
&a7,
&ExitStatus,
&a9);
v38 = EnclaveReturnFrame;
*((_DWORD *)CurrentThread + 325) &= ~0x200u;
KiLeaveGuardedRegionUnsafe((__int64)CurrentThread);
if( a9 )
ZwTerminateProcess((PVOID)0xFFFFFFFFFFFFFFFFi64, (unsigned int)ExitStatus);
if( EnclaveReturnFrame < 0 )
{
if( !v47 )
goto LABEL_87;
v25 = a2a;
if( v47 )
v25 = 0i64;
a2a = v25;
}
v26 = a2a;
if( !a2a )
{
*v49 = a5;
if( v47 )
{
if( (*(_DWORD *)(v16 + 36))-- == 1 )
{
--*((_WORD *)CurrentThread + 242);
ExAcquirePushLockExclusiveEx((UINT64)(v10 + 112), 0i64);
RtlAvlRemoveNode((unsigned __int64 *)v10 + 13, (__int64 *)v16);
if( (_InterlockedExchangeAdd64((volatile signed __int64 *)v10 + 14, 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
ExfTryToWakePushLock((volatile INT64 *)v10 + 14);
KeAbPostRelease(v10 + 112);
KeLeaveCriticalRegionThread((__int64)CurrentThread);
v10 = (char *)v35;
}
}
goto LABEL_87;
}
--*((_WORD *)CurrentThread + 243);
LODWORD(a6) = ExitStatus;
EnclaveReturnFrame = RtlCreateEnclaveReturnFrame(
v44,
v23,
v24,
*((_QWORD *)v10 + 1),
v26,
(UINT64)a6,
v41,
a7,
a5,
(*((_DWORD *)CurrentThread + 29) & 0x100000) != 0);
KiLeaveGuardedRegionUnsafe((__int64)CurrentThread);
if( v47 )
goto LABEL_87;
v27 = *(_DWORD *)(v16 + 36);
if( v27 )
goto LABEL_81;
*(_DWORD *)(v16 + 32) = v36;
--*((_WORD *)CurrentThread + 242);
ExAcquirePushLockExclusiveEx((UINT64)v15, 0i64);
v28 = (_QWORD *)*v42;
v29 = 0;
v34 = 0;
if( !v28 )
goto LABEL_78;
while( (int)MiHotPatchImageTreeCompare((UINT64)CurrentThread, (INT64)v28) >= 0 )
{
v30 = (_QWORD *)v28[1];
if( !v30 )
{
v29 = 1;
v34 = 1;
goto LABEL_78;
}
LABEL_76:
v28 = v30;
}
v30 = (_QWORD *)*v28;
if( *v28 )
goto LABEL_76;
v29 = 0;
v34 = 0;
LABEL_78:
RtlAvlInsertNodeEx(v42, (__int64)v28, v29, (_QWORD *)v16);
if( (_InterlockedExchangeAdd64(v15, 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
ExfTryToWakePushLock(v15);
KeAbPostRelease((PVOID)v15);
KeLeaveCriticalRegionThread((__int64)CurrentThread);
v27 = *(_DWORD *)(v16 + 36);
v10 = (char *)v35;
LABEL_81:
*(_DWORD *)(v16 + 36) = v27 + 1;
LABEL_87:
if( !v10[76] && !*(_DWORD *)(v16 + 36) )
{
--*((_WORD *)CurrentThread + 242);
ExAcquirePushLockExclusiveEx((UINT64)(v10 + 112), 0i64);
*(_QWORD *)v16 = *((_QWORD *)v10 + 16);
*((_QWORD *)v10 + 16) = v16;
PspReleaseEnclaveThread((INT64)v10);
if( (_InterlockedExchangeAdd64((volatile signed __int64 *)v10 + 14, 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
ExfTryToWakePushLock((volatile INT64 *)v10 + 14);
KeAbPostRelease(v10 + 112);
KeLeaveCriticalRegionThread((__int64)CurrentThread);
goto LABEL_92;
}
LABEL_93:
PsDereferenceVsmEnclave(v10);
return(unsigned int)EnclaveReturnFrame;
}Referenced by:
NtCallEnclave