KiExpandKernelStackAndCalloutOnStackSegment
__int64 __fastcall KiExpandKernelStackAndCalloutOnStackSegment(
VOID (*a1)(void),
void *a2,
unsigned __int64 a3,
char a4,
__int64 a5){
char v5;
unsigned __int64 v6;
_ETHREAD *CurrentThread;
unsigned __int8 v8;
unsigned int v9;
unsigned __int8 CurrentIrql;
__int64 v11;
unsigned int v12;
int v13;
int v14;
_QWORD *KernelStack;
_KPROFILE_SOURCE v16;
UINT64 v17;
_QWORD *v18;
INT64 v19;
__int64 v20;
__int32 bf_0;
int v22;
UINT64 v23;
unsigned int v24;
unsigned int v25;
__int64 v27;
__int64 v28;
__int64 v29;
bool v30;
unsigned __int8 v31;
PLARGE_INTEGER v32;
__int64 v33;
UINT64 v34;
struct _KPRCB *v35;
int v38;
UINT64 DeleteFlags;
v5 = a4;
v33 = 0i64;
v6 = a3;
CurrentThread = (_ETHREAD *)KeGetCurrentThread();
v8 = 0;
v9 = 0;
v32 = 0i64;
CurrentIrql = KeGetCurrentIrql();
v11 = a5;
if( CurrentIrql == 2 )
{
v32 = (PLARGE_INTEGER)&v33;
if( a5 )
v8 = 16;
}
if( (a4 & 8) != 0 && a5 )
v8 = 16;
v12 = 0;
if( a3 > (unsigned int)KeKernelStackSize )
{
v8 |= 1u;
v12 = 1;
v9 = 1;
if( a5 && *(_BYTE *)(a5 + 4) )
v12 = 5;
}
else
{
v5 = a4 | 4;
v6 = 0i64;
}
LODWORD(DeleteFlags) = v9;
if( (v8 & 0xF0) == 0 )
{
v13 = v12 | 2;
if( (v5 & 2) != 0 )
v13 = v12;
v12 = v13 | 0x10;
v14 = v5 & 4;
if( !v14 )
v12 = v13;
KernelStack = MmCreateKernelStack(
v12,
LOBYTE((*(&KiProcessorBlock + CurrentThread->Tcb.IdealProcessor))->ParentNode->NodeNumber),
&CurrentThread->Tcb);
v9 |= 4u;
v18 = KernelStack;
if( !v14 )
v9 = DeleteFlags;
if( KernelStack )
goto LABEL_13;
v11 = a5;
}
if( !v11 || (v8 & 1) != 0 && !*(_BYTE *)(v11 + 4) )
return 3221225495i64;
if( _bittestandset((signed __int32 *)&CurrentThread->Tcb.116, 0xFu) )
v8 |= 4u;
if( KeWaitForSingleObject(v11 + 8, 25, 0, 0, (INT64)v32) == 258 )
{
CurrentThread->Tcb._bf_0 ^= (CurrentThread->Tcb._bf_0 ^ (v8 << 13)) & 0x8000;
return 3221227272i64;
}
v27 = *(unsigned __int8 *)(v11 + 6);
if( (unsigned __int8)v27 >= *(_BYTE *)(v11 + 5) )
{
KeReleaseMutant((_KMUTANT *)(v11 + 8), 1i64, 0, 0);
return 3221225495i64;
}
v18 = *(_QWORD **)(v11 + 8 * v27 + 64);
v8 |= 8u;
v28 = a5;
*(_BYTE *)(a5 + 6) = v27 + 1;
if( (v8 & 1) == 0 && *(_BYTE *)(v28 + 4) )
{
LOBYTE(v12) = 5;
v6 = 71680i64;
v8 |= 1u;
}
LABEL_13:
*(v18 - 6) = v18;
v19 = (INT64)(v18 - 6);
if( (v8 & 1) != 0 )
{
v20 = (__int64)v18 - 73727;
}
else
{
v17 = (unsigned int)KeKernelStackSize;
v20 = (__int64)v18 - (unsigned int)KeKernelStackSize + 1;
}
*(_QWORD *)(v19 + 8) = v20;
*(_QWORD *)(v19 + 16) = CurrentThread->Tcb.StackBase;
*(_QWORD *)(v19 + 40) = CurrentThread->Tcb.InitialStack;
if( (v12 & 1) != 0 )
{
v19 |= 1ui64;
if( (v12 & 4) != 0 )
v19 |= 2ui64;
}
bf_0 = CurrentThread->Tcb._bf_0;
if( (bf_0 & 0x1000) != 0 )
{
v8 |= 2u;
LOBYTE(DeleteFlags) = 2;
}
else
{
LOBYTE(DeleteFlags) = 0;
CurrentThread->Tcb._bf_0 = bf_0 | 0x1000;
}
v22 = 0;
v35 = 0i64;
v34 = 0i64;
v38 = 0;
LODWORD(v23) = KeGetCurrentStackPointer(v17, v16);
KeQueryCurrentStackInformationEx(v23, (char *)&v38, &v35, &v34);
if( v38 == 10 )
{
v22 = 1;
__writegsbyte(0x80A6u, 1u);
}
KiSwitchKernelStackAndCallout((INT64)a2, a1, v19, v6);
v25 = v24;
if( v22 )
__writegsbyte(0x80A6u, 0);
if( (v8 & 8) != 0 )
{
v29 = a5;
v30 = (*(_BYTE *)(a5 + 6))-- == 1;
if( v30 && (v8 & 4) == 0 )
CurrentThread->Tcb._bf_0 &= ~0x8000u;
KeReleaseMutant((_KMUTANT *)(v29 + 8), 1i64, 0, 0);
}
else
{
MmDeleteKernelStack(v18, v9);
}
if( !(_BYTE)DeleteFlags )
CurrentThread->Tcb._bf_0 &= ~0x1000u;
if( KeGetCurrentIrql() != CurrentIrql )
{
v31 = KeGetCurrentIrql();
KeBugCheckEx(0xC8u, (PVOID)(((CurrentIrql | ((unsigned __int64)v31 << 8)) << 8) | 2), a1, a2, 0i64);
}
return v25;
}Referenced by:
KiExpandKernelStackAndCalloutSwitchStack