KeAbCrossThreadDelete
INT8 __stdcall KeAbCrossThreadDelete(VOID *Lock, _ETHREAD *Thread){
__int64 v4;
int v5;
unsigned __int64 v6;
NTSTATUS SessionId;
unsigned int v8;
_KLOCK_ENTRY *v9;
int v10;
__int128 v11;
unsigned __int8 v12;
__int64 v13;
__int128 v14;
unsigned __int8 v15;
__int64 v17;
unsigned __int8 CurrentIrql;
_KPRCB *v19;
char v20;
volatile unsigned int NextProcessor;
int v23[8];
_KPRCB *ControlPrcb;
__int128 v25;
__int128 Object;
__int128 v27;
__int128 v28;
_KDPC Dpc;
UINT64 SpinCount;
_KSHARED_READY_QUEUE *ControlReadyQueue;
Object = 0i64;
v27 = 0i64;
v28 = 0i64;
memset(&Dpc, 0i64, sizeof(Dpc));
LODWORD(v4) = (char)Thread->Tcb.AbEntrySummary;
v5 = v4 | (char)Thread->Tcb.AbOrphanedEntrySummary;
ControlPrcb = 0i64;
ControlReadyQueue = 0i64;
if( v5 != 63 )
{
v6 = (unsigned __int64)Lock & 0x7FFFFFFFFFFFFFFCi64;
if( MmIsSessionAddress(Lock) )
SessionId = MmGetSessionIdEx(KeGetCurrentThread()->ApcState.Process);
else
SessionId = -1;
LODWORD(v4) = (char)Thread->Tcb.AbEntrySummary;
v8 = (v4 | (char)Thread->Tcb.AbOrphanedEntrySummary) ^ 0x3F;
while( 1 )
{
if( !_BitScanReverse((unsigned int *)&v17, v8) )
return v4;
v9 = &Thread->Tcb.LockEntries[v17];
v8 &= ~(1 << v17);
v4 = v9->LockState.$E8276A2CF8B819ED32D1B6FEB35D730A::_bf_0 & 0x7FFFFFFFFFFFFFFCi64;
if( v4 == v6 )
{
*(_QWORD *)&v11 = v9->LockState.$E8276A2CF8B819ED32D1B6FEB35D730A::_bf_0;
*((_QWORD *)&v11 + 1) = _mm_srli_si128((__m128i)v9->32, 8).m128i_u64[0];
v12 = _InterlockedCompareExchange128(
&v9->LockState.$E8276A2CF8B819ED32D1B6FEB35D730A::_bf_0,
*((signed __int64 *)&v11 + 1),
v11,
(signed __int64 *)&v11);
LOBYTE(v4) = v11;
v10 = DWORD2(v11);
v13 = v11;
v25 = v11;
if( v12
|| (*(_QWORD *)&v14 = v9->LockState.$E8276A2CF8B819ED32D1B6FEB35D730A::_bf_0,
*((_QWORD *)&v14 + 1) = _mm_srli_si128((__m128i)v9->32, 8).m128i_u64[0],
v15 = _InterlockedCompareExchange128(
&v9->LockState.$E8276A2CF8B819ED32D1B6FEB35D730A::_bf_0,
*((signed __int64 *)&v14 + 1),
v14,
(signed __int64 *)&v14),
LOBYTE(v4) = v14,
v10 = DWORD2(v14),
v13 = v14,
v25 = v14,
v15) )
{
if( (v9->AcquiredByte & 1) != 0 )
{
LOBYTE(v4) = v13 & 0xFC;
if( (v13 & 0x7FFFFFFFFFFFFFFCi64) == v6 && v10 == SessionId )
break;
}
}
}
}
if( v13 >= 0 )
{
CurrentIrql = KeGetCurrentIrql();
__writecr8(2ui64);
LODWORD(SpinCount) = 0;
while( _interlockedbittestandset64((volatile signed __int32 *)&Thread->Tcb.ThreadLock, 0i64) )
{
do
KeYieldProcessorEx(&SpinCount);
while( Thread->Tcb.ThreadLock );
}
KiAcquireThreadStateLock(Thread, &ControlPrcb, &ControlReadyQueue);
if( v20 == 2 )
{
NextProcessor = Thread->Tcb.NextProcessor;
KiReleaseThreadStateLock(v19, (_KSHARED_READY_QUEUE *)ControlPrcb);
KiReleaseThreadLockSafe((INT64)Thread);
__writecr8(CurrentIrql);
Dpc.DpcData = 0i64;
*(_QWORD *)&v27 = (char *)&Object + 8;
*((_QWORD *)&Object + 1) = (char *)&Object + 8;
Dpc.DeferredRoutine = (void(__fastcall *)(_KDPC *, void *, void *, void *))KeAbCrossThreadDeleteDpcRoutine;
Dpc.DeferredContext = &Object;
*((_QWORD *)&v27 + 1) = Lock;
*(_QWORD *)&v28 = v9;
*((_QWORD *)&v28 + 1) = Thread;
LOWORD(Object) = 1;
BYTE2(Object) = 6;
DWORD1(Object) = 0;
LOWORD(Dpc.TargetInfoAsUlong) = 275;
Dpc.ProcessorHistory = 0i64;
Dpc.Number = NextProcessor + 1280;
KiInsertQueueDpc(&Dpc, 0i64, 0i64, 0i64, 0);
KeWaitForSingleObject((UINT64)&Object, 0, 0, 0, 0i64);
LABEL_25:
_InterlockedOr(v23, 0);
LOBYTE(v4) = KiAbCrossThreadRelease(Lock, v9, &Thread->Tcb);
return v4;
}
if( Thread->Tcb.Running )
{
KiReleaseThreadStateLock(v19, (_KSHARED_READY_QUEUE *)ControlPrcb);
KiReleaseThreadLockSafe((INT64)Thread);
__writecr8(CurrentIrql);
KeGenericCallDpc((__int64)KeAbCrossThreadDeleteNopDpcRoutine, 0i64);
}
else
{
KiReleaseThreadStateLock(v19, (_KSHARED_READY_QUEUE *)ControlPrcb);
KiReleaseThreadLockSafe((INT64)Thread);
__writecr8(CurrentIrql);
}
}
v9->CrossThreadReleasableAndBusyByte |= 1u;
goto LABEL_25;
}
return v4;
}Referenced by:
KeDeleteMutant