NtFreeUserPhysicalPages
NTSTATUS __stdcall NtFreeUserPhysicalPages(PVOID ProcessHandle, UINT64 *NumberOfPages, UINT64 *UserPfnArray){
__int64 v5;
unsigned __int64 v6;
__int64 v7;
NTSTATUS v8;
_MDL *Mdl;
int v10;
__int64 v11;
INT64 v12;
NTSTATUS v13;
IRP *Irp;
unsigned __int64 v15;
unsigned __int64 v16;
UINT64 v17;
UINT8 *v18;
__int64 v19;
INT64 AweInfoPartition;
__int64 v21;
unsigned __int64 v22;
__int64 v23;
__int16 v24;
__int64 v25;
char v26;
_EPROCESS *PROCESS;
INT64 v28;
UINT64 v30;
UINT64 v31;
_ETHREAD *CurrentThread;
__int64 ByteOffset;
UINT64 v34;
struct _KAPC_STATE ApcState;
INT64 result[518];
memset(&ApcState, 0, sizeof(ApcState));
memset((INT64)result, 0i64);
CurrentThread = (_ETHREAD *)KeGetCurrentThread();
v5 = *((_QWORD *)CurrentThread + 23);
v26 = *((_BYTE *)CurrentThread + 562);
if( v26 )
{
v7 = (__int64)NumberOfPages;
if( (unsigned __int64)NumberOfPages >= 0x7FFFFFFF0000i64 )
v7 = 0x7FFFFFFF0000i64;
*(_QWORD *)v7 = *(_QWORD *)v7;
v6 = *NumberOfPages;
v30 = *NumberOfPages;
*NumberOfPages = 0i64;
}
else
{
v6 = *NumberOfPages;
v30 = *NumberOfPages;
}
if( !v6 )
return -1073741584;
Mdl = (_MDL *)result;
v8 = MiReferenceAweHandle(ProcessHandle, 2i64);
if( v8 >= 0 )
{
v10 = 4;
PROCESS = (_EPROCESS *)v5;
v11 = v5;
v31 = 0i64;
v12 = *(_QWORD *)(*(_QWORD *)(v5 + 1680) + 392i64);
v28 = v12;
if( v12 )
{
v15 = ExGetCallBackBlockRoutine(v12);
Mdl = (_MDL *)Irp;
v16 = 512i64;
if( v6 > 0x200 / v15 )
{
if( v6 <= 0xC0000 / v15 )
v16 = v6 * v15;
else
v16 = ~(v15 - 1) & 0xC0000;
while( v16 > 0x200 )
{
Mdl = IoAllocateMdl(0i64, (_DWORD)v16 << 12, 0, 0, Irp);
Irp = 0i64;
if( Mdl )
break;
v16 = ~(v15 - 1) & (v15 + (v16 >> 1) - 1);
}
}
if( !Mdl )
{
Mdl = (_MDL *)result;
v16 = 512i64;
}
v17 = v16 / v15;
while( 1 )
{
if( v6 < v17 )
v17 = v6;
v34 = v17;
Mdl->Next = (_MDL *)Irp;
Mdl->Size = 8 * ((((v17 << 12) + 4095) >> 12) + 6);
Mdl->MdlFlags = (__int16)Irp;
Mdl->StartVa = Irp;
Mdl->ByteOffset = (unsigned int)Irp;
Mdl->ByteCount = (_DWORD)v17 << 12;
v10 &= ~1u;
v18 = (UINT8 *)&Mdl[1];
if( v26 == (_BYTE)Irp )
{
memmove(v18, (UINT8 *)UserPfnArray, 8 * v17);
}
else
{
v13 = MiCaptureUlongPtrArray(v18, UserPfnArray, v17);
if( v13 < 0 )
goto LABEL_45;
}
if( *((_QWORD *)CurrentThread + 23) != v11 )
{
KeStackAttachProcess((PRKPROCESS)v11, &ApcState);
v10 |= 1u;
}
LOCK_ADDRESS_SPACE((__int64)CurrentThread, v11);
if( (*(_DWORD *)(v11 + 1124) & 0x20) != 0 )
break;
v13 = MiFreePhysicalPages(v28, (INT64)Mdl);
ByteOffset = Mdl->ByteOffset;
if( Mdl->ByteOffset )
{
MiReturnProcessCommitment(v11, v15 * Mdl->ByteOffset);
v31 += v19;
}
UNLOCK_ADDRESS_SPACE((__int64)CurrentThread, v11);
Irp = 0i64;
if( Mdl->ByteCount )
{
AweInfoPartition = MiGetAweInfoPartition(v28);
v22 = -(__int64)(v15 * v21);
_InterlockedExchangeAdd64((volatile signed __int64 *)(AweInfoPartition + 7608), v22);
_InterlockedExchangeAdd64((volatile signed __int64 *)PROCESS + 254, v22);
Mdl->MdlFlags |= 2u;
Mdl->ByteCount <<= 12;
MiPreparePhysicalPagesMdlForFree((INT64)Mdl, v15);
MiFreePagesFromMdl(Mdl, 0i64);
v6 = v30;
v11 = (__int64)PROCESS;
Irp = 0i64;
}
v6 -= ByteOffset;
v30 = v6;
if( v13 || !v6 )
goto LABEL_45;
if( (v10 & 1) != 0 )
{
KeUnstackDetachProcess(&ApcState);
v10 &= ~1u;
Irp = 0i64;
}
v23 = *(_QWORD *)(v11 + 1408);
if( v23 && ((v24 = *(_WORD *)(v23 + 8), v24 == 332) || v24 == 452) )
v25 = 4i64;
else
v25 = 8i64;
v17 = v34;
UserPfnArray = (UINT64 *)((char *)UserPfnArray + v34 * v25);
}
UNLOCK_ADDRESS_SPACE((__int64)CurrentThread, v11);
v13 = -1073741558;
}
else
{
v13 = -1073741585;
}
LABEL_45:
if( Mdl != (_MDL *)result )
{
Mdl->MdlFlags &= ~2u;
IoFreeMdl(Mdl);
}
if( (v10 & 1) != 0 )
KeUnstackDetachProcess(&ApcState);
if( (v10 & 4) == 0 )
ObfDereferenceObjectWithTag((PVOID)v11, 0x68506D4Dui64);
*NumberOfPages = v31;
return v13;
}
return v8;
}Referenced by:
No references.