KiExpandKernelStackAndCalloutOnStackSegment
__int64 __fastcall KiExpandKernelStackAndCalloutOnStackSegment(
void (*a1)(void),
ULONG_PTR a2,
unsigned __int64 a3,
char a4,
__int64 a5){
char v5;
__int64 v6;
_ETHREAD *CurrentThread;
unsigned __int8 v8;
unsigned int v9;
unsigned __int8 CurrentIrql;
__int64 v11;
int v12;
int v13;
int v14;
__int64 KernelStack;
KPROFILE_SOURCE v16;
UINT64 v17;
_QWORD *v18;
__int64 v19;
__int64 v20;
int v21;
int v22;
UINT64 v23;
unsigned int v24;
unsigned int v25;
__int64 v27;
__int64 v28;
__int64 v29;
bool v30;
unsigned __int8 v31;
int Timeout;
int v33;
union _LARGE_INTEGER *v34;
__int64 v35;
UINT64 a4a;
void *a3a[10];
int a2a;
UINT64 DeleteFlags;
v5 = a4;
v35 = 0i64;
v6 = a3;
CurrentThread = (_ETHREAD *)KeGetCurrentThread();
v8 = 0;
v9 = 0;
v34 = 0i64;
CurrentIrql = KeGetCurrentIrql();
v11 = a5;
if( CurrentIrql == 2 )
{
v34 = (union _LARGE_INTEGER *)&v35;
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,
*(unsigned __int8 *)(*((_QWORD *)*(&KiProcessorBlock + *((unsigned int *)CurrentThread + 147)) + 24)
+ 146i64),
(unsigned __int64)CurrentThread);
v9 |= 4u;
v18 = (_QWORD *)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 + 29, 0xFu) )
v8 |= 4u;
if( KeWaitForSingleObject((PVOID)(v11 + 8), WrCalloutStack, 0, 0, v34) == 258 )
{
*((_DWORD *)CurrentThread + 29) ^= (*((_DWORD *)CurrentThread + 29) ^ (v8 << 13)) & 0x8000;
return 3221227272i64;
}
v27 = *(unsigned __int8 *)(v11 + 6);
if( (unsigned __int8)v27 >= *(_BYTE *)(v11 + 5) )
{
KeReleaseMutant((PRKMUTANT)(v11 + 8), 1, 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) = *((_QWORD *)CurrentThread + 7);
*(_QWORD *)(v19 + 40) = *((_QWORD *)CurrentThread + 5);
if( (v12 & 1) != 0 )
{
v19 |= 1ui64;
if( (v12 & 4) != 0 )
v19 |= 2ui64;
}
v21 = *((_DWORD *)CurrentThread + 29);
if( (v21 & 0x1000) != 0 )
{
v8 |= 2u;
LOBYTE(DeleteFlags) = 2;
}
else
{
LOBYTE(DeleteFlags) = 0;
*((_DWORD *)CurrentThread + 29) = v21 | 0x1000;
}
v22 = 0;
a3a[0] = 0i64;
a4a = 0i64;
a2a = 0;
LODWORD(v23) = KeGetCurrentStackPointer(v17, v16);
KeQueryCurrentStackInformationEx(v23, &a2a, (CHAR **)a3a, &a4a);
if( a2a == 10 )
{
v22 = 1;
__writegsbyte(0x80A6u, 1u);
}
KiSwitchKernelStackAndCallout(a2, a1, v19, v6, Timeout, v33, (__int64)v34);
v25 = v24;
if( v22 )
__writegsbyte(0x80A6u, 0);
if( (v8 & 8) != 0 )
{
v29 = a5;
v30 = (*(_BYTE *)(a5 + 6))-- == 1;
if( v30 && (v8 & 4) == 0 )
*((_DWORD *)CurrentThread + 29) &= ~0x8000u;
KeReleaseMutant((PRKMUTANT)(v29 + 8), 1, 0, 0);
}
else
{
MmDeleteKernelStack(v18, v9);
}
if( !(_BYTE)DeleteFlags )
*((_DWORD *)CurrentThread + 29) &= ~0x1000u;
if( KeGetCurrentIrql() != CurrentIrql )
{
v31 = KeGetCurrentIrql();
KeBugCheckEx(0xC8u, ((CurrentIrql | ((unsigned __int64)v31 << 8)) << 8) | 2, (ULONG_PTR)a1, a2, 0i64);
}
return v25;
}Referenced by:
KiExpandKernelStackAndCalloutSwitchStack