ObWaitForMultipleObjects
NTSTATUS __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;
_EPROCESS *Process;
char v12;
_HANDLE_TABLE *ObjectTable;
INT8 v14;
__int64 v15;
unsigned int v16;
unsigned __int64 v17;
_OBJECT_HEADER *v18;
_EXHANDLE v19;
_HANDLE_TABLE *v20;
_HANDLE_TABLE_ENTRY *v21;
_HANDLE_TABLE_ENTRY *v22;
__int64 LowValue;
__int64 v24;
_HANDLE_TABLE_ENTRY v25;
unsigned __int8 v26;
_OBJECT_HEADER *v27;
__int32 v28;
_QUAD *p_Body;
unsigned __int64 v30;
_WAIT_TYPE v31;
__int64 v32;
__int64 v33;
unsigned int v34;
bool v35;
VOID *v36;
NTSTATUS v37;
_EX_RUNDOWN_REF *v38;
VOID **v39;
unsigned __int64 v41;
void *PoolWithTag;
_OBJECT_HEADER *v43;
NTSTATUS v44;
VOID **v45;
unsigned int v46;
unsigned int v47;
VOID *v48;
__int64 v49;
VOID *v50;
char *v51;
NTSTATUS v52;
__int64 v53;
void *v54;
unsigned int v55;
PVOID *v56;
__int64 v57;
int v58[8];
INT8 v59;
char v60;
char v61;
INT8 v62;
PVOID P;
unsigned __int64 v64;
_EX_RUNDOWN_REF *v65;
_ETHREAD *Thread;
_HANDLE_TABLE_ENTRY HandleData;
_WAIT_TYPE WaitTypea;
unsigned int Counta;
NTSTATUS Count_4;
int v71;
_HANDLE_TABLE *v72;
_NPAGED_LOOKASIDE_LIST *Lookaside;
VOID **v74;
_LARGE_INTEGER *v75;
_EPROCESS *v76;
VOID *Object[64];
__int64 v78[64];
WaitTypea = WaitType;
v59 = AccessMode;
v7 = CapturedHandles;
v74 = CapturedHandles;
v8 = (unsigned int)Count;
Counta = Count;
v75 = Timeout;
HandleData = 0i64;
memset(v78, 0i64, sizeof(v78));
v64 = 0i64;
memset(Object, 0i64, sizeof(Object));
v62 = 0;
v61 = 0;
P = 0i64;
v9 = 0;
Lookaside = 0i64;
if( (unsigned int)v8 > 3 )
{
v41 = 48 * v8;
if( (unsigned int)v8 > 0xA )
{
Lookaside = &ObpWaitBlockLookaside + ((int)v8 - 11) / 0xEu;
PoolWithTag = ExAllocateFromNPagedLookasideList(Lookaside);
}
else
{
PoolWithTag = ExAllocatePoolWithTag(0x200ui64, 48 * v8, 1834443343i64);
}
P = PoolWithTag;
if( PoolWithTag )
{
v61 = 1;
}
else
{
v62 = KeSetKernelStackSwapEnable(0);
v53 = v41 + 15;
if( v41 + 15 <= v41 )
v53 = 0xFFFFFFFFFFFFFF0i64;
v54 = alloca(v53 & 0xFFFFFFFFFFFFFFF0ui64);
P = &v59;
}
}
v60 = 0;
CurrentThread = (_ETHREAD *)KeGetCurrentThread();
Thread = CurrentThread;
Process = CurrentThread->Tcb.ApcState.Process;
v65 = (_EX_RUNDOWN_REF *)Process;
v76 = Process;
v12 = 1;
--CurrentThread->Tcb.KernelApcDisable;
if( Process == CurrentThread->Tcb.Process )
{
ObjectTable = Process->ObjectTable;
v72 = ObjectTable;
LABEL_4:
v14 = v59;
goto LABEL_5;
}
ObjectTable = ObReferenceProcessHandleTable(Process);
v72 = ObjectTable;
if( ObjectTable )
{
v60 = 1;
goto LABEL_4;
}
v55 = 0;
if( !(_DWORD)v8 )
goto LABEL_4;
v56 = v7;
v14 = v59;
while( ObpIsKernelHandle(*v56, v14) )
{
++v55;
v56 = (PVOID *)(v57 + 8);
if( v55 >= (unsigned int)v8 )
{
ObjectTable = v72;
LABEL_5:
v15 = 0i64;
v16 = 1;
v17 = 0x140000000ui64;
v18 = (_OBJECT_HEADER *)v64;
while( 2 )
{
v19 = (_EXHANDLE)v7[v15];
if( v14 || (v19.Value & 0xFFFFFFFF80000000ui64) != 0xFFFFFFFF80000000ui64 || v19.Value > 0xFFFFFFFFFFFFFFFDui64 )
{
v20 = ObjectTable;
}
else
{
v19 = (_EXHANDLE)(v19.Value ^ 0xFFFFFFFF80000000ui64);
v20 = HandleTable;
}
if( (v19._bf_0 & 0x3FC) != 0 )
{
v21 = ExpLookupHandleTableEntry(v20, v19);
v22 = v21;
if( v21 )
{
_m_prefetchw(v21);
HandleData = *v21;
LABEL_11:
LowValue = HandleData.LowValue;
while( (LowValue & 0x1FFFE) != 0 )
{
if( (LowValue & 1) == 0 )
{
ExpBlockOnLockedHandleEntry(v20, v22, LowValue);
_m_prefetchw(v22);
HandleData = *v22;
goto LABEL_11;
}
v25.LowValue = LowValue;
v25.HighValue = HandleData.HighValue;
v26 = _InterlockedCompareExchange128(&v22->VolatileLowValue, v25.HighValue, LowValue - 2, &v25.LowValue);
v24 = v25.LowValue;
LowValue = v25.LowValue;
HandleData = v25;
if( v26 )
{
if( (unsigned __int16)((unsigned __int64)v24 >> 1) != 16 )
{
v18 = (_OBJECT_HEADER *)((v24 >> 16) & 0xFFFFFFFFFFFFFFF0ui64);
v64 = (unsigned __int64)v18;
v16 = 1;
LABEL_17:
v14 = v59;
v17 = 0x140000000ui64;
goto LABEL_18;
}
HandleData.LowValue = v24 ^ ((unsigned int)v24 ^ (2 * (unsigned int)((unsigned __int64)v24 >> 1) - 2)) & 0x1FFFE;
v18 = (_OBJECT_HEADER *)((HandleData.LowValue >> 16) & 0xFFFFFFFFFFFFFFF0ui64);
v64 = (unsigned __int64)v18;
ObpIncrPointerCountEx(v18, 32752i64);
v52 = ExFastReplenishHandleTableEntry(v22, &HandleData, 32752i64);
v16 = 1;
if( !v52 )
goto LABEL_17;
_InterlockedExchangeAdd64(&v18->PointerCount, -v52);
LABEL_58:
v18 = (_OBJECT_HEADER *)v64;
goto LABEL_17;
}
}
if( ExLockHandleTableEntry(v20, v22) )
{
v64 = (v22->LowValue >> 16) & 0xFFFFFFFFFFFFFFF0ui64;
v43 = (_OBJECT_HEADER *)v64;
HandleData = *v22;
v44 = ExSlowReplenishHandleTableEntry(v22);
ObpIncrPointerCountEx(v43, (unsigned int)(v44 + 1));
v16 = 1;
_InterlockedExchangeAdd64(&v22->VolatileLowValue, 1ui64);
_InterlockedOr(v58, 0);
if( v20->HandleContentionEvent._bf_0 )
{
ExfUnblockPushLock(&v20->HandleContentionEvent._bf_0, 0i64);
v16 = 1;
}
goto LABEL_58;
}
v18 = (_OBJECT_HEADER *)v64;
v14 = v59;
v16 = 1;
v17 = 0x140000000ui64;
}
}
if( v19 )
{
ExHandleLogBadReference(v20, v19.GenericHandleOverlay, KeGetCurrentThread()->PreviousMode);
v18 = (_OBJECT_HEADER *)v64;
v14 = v59;
v16 = 1;
v17 = 0x140000000ui64;
}
v22 = 0i64;
LABEL_18:
v27 = v18;
if( !v22 )
{
LABEL_60:
v37 = -1073741816;
LABEL_61:
CurrentThread = Thread;
v12 = 1;
goto LABEL_62;
}
v28 = HandleData.LeafHandleValue.$E5B3C52FE72490EE6A49ADBB8529F30E::_bf_0 & 0x1FFFFFF;
v71 = ++v9;
p_Body = &v18->Body;
v78[v15] = (__int64)&v18->Body;
if( v14 == 1 )
{
if( (~v28 & 0x100000) != 0 )
{
v37 = -1073741790;
goto LABEL_61;
}
if( (v18->InfoMask & 0x40) != 0 )
{
v51 = (char *)v18 - *(unsigned __int8 *)((v18->InfoMask & 0x7F) + v17 + 12737888);
if( *(_BYTE *)(*(_QWORD *)v51 + 24i64) )
{
if( *(_QWORD *)(*(_QWORD *)v51 + 16i64) == 1i64 )
{
v37 = -1073700858;
goto LABEL_61;
}
v18 = (_OBJECT_HEADER *)v64;
}
}
}
v30 = (unsigned __int64)v27 >> 8;
v31 = WaitTypea;
if( WaitTypea != WaitAny
&& *(POBJECT_TYPE *)(v17
+ 8
* ((unsigned __int8)ObHeaderCookie ^ (unsigned __int8)v30 ^ (unsigned __int64)v18->TypeIndex)
+ 13614720) == IoCompletionObjectType )
{
goto LABEL_60;
}
if( *(&WheapDeferredInternalLogsEventLock + 56)
&& *(_QWORD *)(v17
+ 8 * ((unsigned __int8)ObHeaderCookie ^ (unsigned __int8)v30 ^ (unsigned __int64)v18->TypeIndex)
+ 13614720) == *(&WheapDeferredInternalLogsEventLock + 56) )
{
v37 = -1073741788;
goto LABEL_61;
}
if( ObpTraceFlags )
{
ObpPushStackInfo(v18, 1u, v16, 0x7457624Fui64);
v16 = 1;
v17 = 0x140000000ui64;
}
v32 = *(_QWORD *)(v17
+ 8
* ((unsigned __int8)v30 ^ (unsigned __int8)ObHeaderCookie ^ (unsigned __int64)v18->TypeIndex)
+ 13614720);
v33 = *(_QWORD *)(v32 + 32);
if( (v33 & 1) != 0 )
{
if( (v33 & 2) != 0 )
{
if( (*(_DWORD *)(v32 + 176) & *(_DWORD *)((_BYTE *)&p_Body->DoNotUseThisField
+ *(unsigned __int16 *)(v32 + 180))) == *(_DWORD *)(v32 + 176) )
{
v33 = *(__int64 *)((char *)&p_Body->UseThisFieldToCopy + *(unsigned __int16 *)(v32 + 182));
}
else
{
v33 -= 3i64;
LABEL_28:
v33 += (__int64)p_Body;
}
}
else
{
v33 = *(__int64 *)((char *)p_Body + v33 - 1);
}
}
else if( v33 >= 0 )
{
goto LABEL_28;
}
Object[v15] = (VOID *)v33;
v15 = (unsigned int)(v15 + 1);
v34 = Counta;
if( (unsigned int)v15 >= Counta )
{
if( v60 )
{
v60 = 0;
ExReleaseRundownProtection(v65 + 139);
}
CurrentThread = Thread;
v35 = Thread->Tcb.KernelApcDisable++ == -1;
if( v35
&& ($F25F8C4BA33AF922A5F1AF68CD89DDDF *)CurrentThread->Tcb.ApcState.ApcListHead[0].Flink != &CurrentThread->Tcb.152
&& !CurrentThread->Tcb.SpecialApcDisable )
{
KiCheckForKernelApcDelivery();
}
v12 = 0;
v59 = 0;
if( v31 == WaitAll && v34 > 1 )
{
v45 = &Object[1];
v46 = 1;
while( 2 )
{
v47 = v46;
v48 = *v45;
do
{
v49 = v47 - 1;
v50 = Object[v49];
if( v48 > v50 )
break;
if( v48 == v50 )
{
v37 = -1073741776;
goto LABEL_62;
}
Object[v47--] = v50;
}
while( (_DWORD)v49 );
Object[v47] = v48;
++v46;
++v45;
if( v46 < v34 )
continue;
break;
}
}
v36 = P;
v37 = KeWaitForMultipleObjects(v34, Object, v31, UserRequest, WaitMode, Alertable, v75, (_KWAIT_BLOCK *)P);
Count_4 = v37;
v38 = v65;
goto LABEL_37;
}
v14 = v59;
ObjectTable = v72;
v7 = v74;
continue;
}
}
}
v37 = -1073741558;
LABEL_62:
v36 = P;
v38 = v65;
LABEL_37:
if( v9 )
{
v39 = (VOID **)&v78[v9];
do
{
ObfDereferenceObjectWithTag(*--v39, 0x7457624Fui64);
--v9;
}
while( v9 );
}
if( v12 )
{
if( v60 )
ExReleaseRundownProtection(v38 + 139);
KeLeaveCriticalRegionThread(&CurrentThread->Tcb);
}
if( v36 )
{
if( v61 )
{
if( Lookaside )
ExFreeToNPagedLookasideList(Lookaside, v36);
else
ExFreePoolWithTag(v36, 0);
}
else
{
KeSetKernelStackSwapEnable(v62);
}
}
return v37;
}Referenced by:
NtWaitForMultipleObjects
NtWaitForMultipleObjects32