ObWaitForMultipleObjects
INT64 __stdcall ObWaitForMultipleObjects(
UINT64 Count,
VOID **CapturedHandles,
INT8 AccessMode,
WAIT_TYPE WaitType,
INT8 WaitMode,
UINT8 Alertable,
LARGE_INTEGER *Timeout){
VOID **v7;
__int64 v8;
int v9;
_ETHREAD *CurrentThread;
struct _EX_RUNDOWN_REF *v11;
char v12;
unsigned __int64 v13;
INT8 v14;
__int64 v15;
unsigned int v16;
unsigned __int64 v17;
unsigned __int64 v18;
ULONG_PTR v19;
_HANDLE_TABLE *v20;
_HANDLE_TABLE_ENTRY *v21;
_HANDLE_TABLE_ENTRY *v22;
INT64 v23;
__int64 v24;
__int128 v25;
unsigned __int8 v26;
unsigned __int64 v27;
int v28;
unsigned __int64 v29;
unsigned __int64 v30;
WAIT_TYPE v31;
__int64 v32;
__int64 v33;
ULONG v34;
bool v35;
PKWAIT_BLOCK v36;
int v37;
unsigned int v38;
struct _EX_RUNDOWN_REF *v39;
PVOID *v40;
unsigned __int64 v42;
struct _KWAIT_BLOCK *PoolWithTag;
volatile INT64 *v44;
int v45;
void **v46;
unsigned int v47;
unsigned int v48;
void *v49;
__int64 v50;
void *v51;
unsigned __int64 v52;
int v53;
__int64 v54;
void *v55;
unsigned int v56;
PVOID *v57;
__int64 v58;
int v59[8];
INT8 v60;
char v61;
char v62;
UINT8 v63;
PKWAIT_BLOCK WaitBlockArray;
unsigned __int64 v65;
struct _EX_RUNDOWN_REF *v66;
_ETHREAD *v67;
INT64 CurrentValue[2];
WAIT_TYPE WaitTypea;
ULONG Counta;
int v71;
int v72;
unsigned __int64 v73;
PNPAGED_LOOKASIDE_LIST Lookaside;
VOID **v75;
PLARGE_INTEGER v76;
struct _EX_RUNDOWN_REF *v77;
PVOID Object;
char v79;
__int64 result[64];
WaitTypea = WaitType;
v60 = AccessMode;
v7 = CapturedHandles;
v75 = CapturedHandles;
v8 = (unsigned int)Count;
Counta = Count;
v76 = Timeout;
*(_OWORD *)CurrentValue = 0i64;
memset((INT64)result, 0i64);
v65 = 0i64;
memset((INT64)&Object, 0i64);
v63 = 0;
v62 = 0;
WaitBlockArray = 0i64;
v9 = 0;
Lookaside = 0i64;
if( (unsigned int)v8 > 3 )
{
v42 = 48 * v8;
if( (unsigned int)v8 > 0xA )
{
Lookaside = (PNPAGED_LOOKASIDE_LIST)&ObpWaitBlockLookaside[16 * (unsigned __int64)(((int)v8 - 11) / 0xEu)];
LODWORD(PoolWithTag) = ExAllocateFromNPagedLookasideList(Lookaside);
}
else
{
PoolWithTag = (struct _KWAIT_BLOCK *)ExAllocatePoolWithTag(NonPagedPoolNx, 48 * v8, 0x6D57624Fui64);
}
WaitBlockArray = PoolWithTag;
if( PoolWithTag )
{
v62 = 1;
}
else
{
v63 = KeSetKernelStackSwapEnable(0);
v54 = v42 + 15;
if( v42 + 15 <= v42 )
v54 = 0xFFFFFFFFFFFFFF0i64;
v55 = alloca(v54 & 0xFFFFFFFFFFFFFFF0ui64);
WaitBlockArray = (PKWAIT_BLOCK)&v60;
}
}
v61 = 0;
CurrentThread = (_ETHREAD *)KeGetCurrentThread();
v67 = CurrentThread;
v11 = (struct _EX_RUNDOWN_REF *)*((_QWORD *)CurrentThread + 23);
v66 = v11;
v77 = v11;
v12 = 1;
--*((_WORD *)CurrentThread + 242);
if( v11 == *((struct _EX_RUNDOWN_REF **)CurrentThread + 68) )
{
v13 = v11[174].Count;
v73 = v13;
LABEL_4:
v14 = v60;
goto LABEL_5;
}
v13 = ObReferenceProcessHandleTable(v11);
v73 = v13;
if( v13 )
{
v61 = 1;
goto LABEL_4;
}
v56 = 0;
if( !(_DWORD)v8 )
goto LABEL_4;
v57 = v7;
v14 = v60;
while( ObpIsKernelHandle(*v57, v14) )
{
++v56;
v57 = (PVOID *)(v58 + 8);
if( v56 >= (unsigned int)v8 )
{
v13 = v73;
LABEL_5:
v15 = 0i64;
v16 = 1;
v17 = 0x140000000ui64;
v18 = v65;
while( 2 )
{
v19 = (ULONG_PTR)v7[v15];
if( v14 || (v19 & 0xFFFFFFFF80000000ui64) != 0xFFFFFFFF80000000ui64 || v19 > 0xFFFFFFFFFFFFFFFDui64 )
{
v20 = (_HANDLE_TABLE *)v13;
}
else
{
v19 ^= 0xFFFFFFFF80000000ui64;
v20 = (_HANDLE_TABLE *)ObpKernelHandleTable;
}
if( (v19 & 0x3FC) != 0 )
{
v21 = ExpLookupHandleTableEntry(v20, (_EXHANDLE)v19);
v22 = v21;
if( v21 )
{
_m_prefetchw(v21);
CurrentValue[0] = v21->LowValue;
CurrentValue[1] = v21->HighValue;
LABEL_11:
v23 = CurrentValue[0];
while( (v23 & 0x1FFFE) != 0 )
{
if( (v23 & 1) == 0 )
{
ExpBlockOnLockedHandleEntry(v20, v22, v23);
_m_prefetchw(v22);
CurrentValue[0] = v22->LowValue;
CurrentValue[1] = v22->HighValue;
goto LABEL_11;
}
*(_QWORD *)&v25 = v23;
*((_QWORD *)&v25 + 1) = CurrentValue[1];
v26 = _InterlockedCompareExchange128(
&v22->VolatileLowValue,
*((signed __int64 *)&v25 + 1),
v23 - 2,
(signed __int64 *)&v25);
v24 = v25;
v23 = v25;
*(_OWORD *)CurrentValue = v25;
if( v26 )
{
if( (unsigned __int16)((unsigned __int64)v24 >> 1) != 16 )
{
v18 = (v24 >> 16) & 0xFFFFFFFFFFFFFFF0ui64;
v65 = v18;
v16 = 1;
LABEL_17:
v14 = v60;
v17 = 0x140000000ui64;
goto LABEL_18;
}
CurrentValue[0] = v24 ^ ((unsigned int)v24 ^ (2 * (unsigned int)((unsigned __int64)v24 >> 1) - 2)) & 0x1FFFE;
v18 = (CurrentValue[0] >> 16) & 0xFFFFFFFFFFFFFFF0ui64;
v65 = v18;
ObpIncrPointerCountEx((volatile INT64 *)v18, 32752i64);
v53 = ExFastReplenishHandleTableEntry(&v22->VolatileLowValue, (unsigned __int64 *)CurrentValue, 32752);
v16 = 1;
if( !v53 )
goto LABEL_17;
_InterlockedExchangeAdd64((volatile signed __int64 *)v18, -v53);
LABEL_58:
v18 = v65;
goto LABEL_17;
}
}
if( ExLockHandleTableEntry((__int64)v20, &v22->LowValue) )
{
v65 = (v22->LowValue >> 16) & 0xFFFFFFFFFFFFFFF0ui64;
v44 = (volatile INT64 *)v65;
*(_HANDLE_TABLE_ENTRY *)CurrentValue = *v22;
v45 = ExSlowReplenishHandleTableEntry((unsigned __int64 *)v22);
ObpIncrPointerCountEx(v44, (unsigned int)(v45 + 1));
v16 = 1;
_InterlockedExchangeAdd64(&v22->VolatileLowValue, 1ui64);
_InterlockedOr(v59, 0);
if( v20->HandleContentionEvent.Value )
{
ExfUnblockPushLock(&v20->HandleContentionEvent, 0i64);
v16 = 1;
}
goto LABEL_58;
}
v18 = v65;
v14 = v60;
v16 = 1;
v17 = 0x140000000ui64;
}
}
if( v19 )
{
ExHandleLogBadReference((ULONG_PTR)v20, v19, *((_BYTE *)KeGetCurrentThread() + 562));
v18 = v65;
v14 = v60;
v16 = 1;
v17 = 0x140000000ui64;
}
v22 = 0i64;
LABEL_18:
v27 = v18;
if( !v22 )
{
LABEL_60:
v38 = -1073741816;
LABEL_61:
CurrentThread = v67;
v12 = 1;
goto LABEL_62;
}
v28 = CurrentValue[1] & 0x1FFFFFF;
v72 = ++v9;
v29 = v18 + 48;
result[v15] = v18 + 48;
if( v14 == 1 )
{
if( (~v28 & 0x100000) != 0 )
{
v38 = -1073741790;
goto LABEL_61;
}
if( (*(_BYTE *)(v18 + 26) & 0x40) != 0 )
{
v52 = v18 - *(unsigned __int8 *)((*(_BYTE *)(v18 + 26) & 0x7F) + v17 + 12737888);
if( *(_BYTE *)(*(_QWORD *)v52 + 24i64) )
{
if( *(_QWORD *)(*(_QWORD *)v52 + 16i64) == 1i64 )
{
v38 = -1073700858;
goto LABEL_61;
}
v18 = v65;
}
}
}
v30 = v27 >> 8;
v31 = WaitTypea;
if( WaitTypea != WaitAny
&& *(POBJECT_TYPE *)(v17
+ 8
* ((unsigned __int8)ObHeaderCookie ^ (unsigned __int8)v30 ^ (unsigned __int64)*(unsigned __int8 *)(v18 + 24))
+ 13614720) == IoCompletionObjectType )
{
goto LABEL_60;
}
if( ExCrossVmMutantObjectType
&& *(POBJECT_TYPE *)(v17
+ 8
* ((unsigned __int8)ObHeaderCookie ^ (unsigned __int8)v30 ^ (unsigned __int64)*(unsigned __int8 *)(v18 + 24))
+ 13614720) == ExCrossVmMutantObjectType )
{
v38 = -1073741788;
goto LABEL_61;
}
if( ObpTraceFlags )
{
ObpPushStackInfo(v18, 1, v16, 1951883855i64);
v16 = 1;
v17 = 0x140000000ui64;
}
v32 = *(_QWORD *)(v17
+ 8
* ((unsigned __int8)v30 ^ (unsigned __int8)ObHeaderCookie ^ (unsigned __int64)*(unsigned __int8 *)(v18 + 24))
+ 13614720);
v33 = *(_QWORD *)(v32 + 32);
if( (v33 & 1) != 0 )
{
if( (v33 & 2) != 0 )
{
if( (*(_DWORD *)(v32 + 176) & *(_DWORD *)(*(unsigned __int16 *)(v32 + 180) + v29)) == *(_DWORD *)(v32 + 176) )
{
v33 = *(_QWORD *)(*(unsigned __int16 *)(v32 + 182) + v29);
}
else
{
v33 -= 3i64;
LABEL_28:
v33 += v29;
}
}
else
{
v33 = *(_QWORD *)(v29 + v33 - 1);
}
}
else if( v33 >= 0 )
{
goto LABEL_28;
}
*(&Object + v15) = (PVOID)v33;
v15 = (unsigned int)(v15 + 1);
v34 = Counta;
if( (unsigned int)v15 >= Counta )
{
if( v61 )
{
v61 = 0;
ExReleaseRundownProtection(v66 + 139);
}
CurrentThread = v67;
v35 = (*((_WORD *)v67 + 242))++ == 0xFFFF;
if( v35
&& *((_ETHREAD **)CurrentThread + 19) != (_ETHREAD *)((char *)CurrentThread + 152)
&& !*((_WORD *)CurrentThread + 243) )
{
KiCheckForKernelApcDelivery();
}
v12 = 0;
v60 = 0;
if( v31 == WaitAll && v34 > 1 )
{
v46 = (void **)&v79;
v47 = 1;
while( 2 )
{
v48 = v47;
v49 = *v46;
do
{
v50 = v48 - 1;
v51 = *(&Object + v50);
if( v49 > v51 )
break;
if( v49 == v51 )
{
v38 = -1073741776;
goto LABEL_62;
}
*(&Object + v48--) = v51;
}
while( (_DWORD)v50 );
*(&Object + v48) = v49;
++v47;
++v46;
if( v47 < v34 )
continue;
break;
}
}
v36 = WaitBlockArray;
KeWaitForMultipleObjects((_BYTE *)v34, &Object, v31, UserRequest, WaitMode, Alertable, v76, WaitBlockArray);
v38 = v37;
v71 = v37;
v39 = v66;
goto LABEL_37;
}
v14 = v60;
v13 = v73;
v7 = v75;
continue;
}
}
}
v38 = -1073741558;
LABEL_62:
v36 = WaitBlockArray;
v39 = v66;
LABEL_37:
if( v9 )
{
v40 = (PVOID *)&result[v9];
do
{
ObfDereferenceObjectWithTag(*--v40, 0x7457624Fui64);
--v9;
}
while( v9 );
}
if( v12 )
{
if( v61 )
ExReleaseRundownProtection(v39 + 139);
KeLeaveCriticalRegionThread((__int64)CurrentThread);
}
if( v36 )
{
if( v62 )
{
if( Lookaside )
ExFreeToNPagedLookasideList(Lookaside, v36);
else
ExFreePoolWithTag(v36, 0);
}
else
{
KeSetKernelStackSwapEnable(v63);
}
}
return v38;
}Referenced by:
NtWaitForMultipleObjects
NtWaitForMultipleObjects32