NtFreeUserPhysicalPages
NTSTATUS __stdcall NtFreeUserPhysicalPages(VOID *ProcessHandle, UINT64 *NumberOfPages, UINT64 *UserPfnArray){
_HANDLE v4;
int v5;
_EPROCESS *v6;
unsigned __int64 v7;
__int64 v8;
NTSTATUS result;
_EX_CALLBACK_ROUTINE_BLOCK *LockedEntries;
_MDL *Mdl;
__int64 v12;
_SECTION *v13;
_EPROCESS *v14;
int v15;
UINT64 v16;
_IRP *v17;
UINT64 v18;
unsigned __int64 v19;
UINT64 v20;
_MDL *v21;
_ETHREAD *v22;
__int64 ByteOffset;
__int64 v24;
__int64 v25;
unsigned __int64 v26;
UINT64 v27;
_EWOW64PROCESS *WoW64Process;
unsigned __int16 Machine;
__int64 v30;
VOID *v31;
_SECTION **Irp;
INT64 v33;
INT64 v34;
_EPROCESS *PROCESS;
INT64 v36;
_SECTION *Section;
VOID *Src;
UINT64 v39;
__int64 v40;
_ETHREAD *Thread;
__int64 v42;
UINT64 v43;
UINT64 *v44;
_KAPC_STATE ApcState;
char v46[4144];
Src = UserPfnArray;
v44 = NumberOfPages;
v4 = (int)ProcessHandle;
memset(&ApcState, 0, sizeof(ApcState));
memset(v46, 0i64, sizeof(v46));
Section = 0i64;
v5 = 0;
Thread = (_ETHREAD *)KeGetCurrentThread();
v6 = Thread->Tcb.ApcState.Process;
LOBYTE(v34) = Thread->Tcb.PreviousMode;
if( (_BYTE)v34 )
{
v8 = (__int64)NumberOfPages;
if( (unsigned __int64)NumberOfPages >= 0x7FFFFFFF0000i64 )
v8 = 0x7FFFFFFF0000i64;
*(_QWORD *)v8 = *(_QWORD *)v8;
v7 = *NumberOfPages;
v39 = *NumberOfPages;
*NumberOfPages = 0i64;
}
else
{
v7 = *NumberOfPages;
v39 = *NumberOfPages;
}
if( !v7 )
return -1073741584;
LockedEntries = 0i64;
v36 = 0i64;
Mdl = (_MDL *)v46;
Irp = &Section;
result = MiReferenceAweHandle(v4, 2i64);
v12 = 0i64;
if( result >= 0 )
{
v13 = Section;
if( Section )
{
LockedEntries = *(_EX_CALLBACK_ROUTINE_BLOCK **)MiSectionControlArea(Section)->gap8;
v36 = (INT64)LockedEntries;
}
else
{
v5 = 4;
}
PROCESS = v6;
v14 = v6;
v40 = v12;
if( LockedEntries
|| (LockedEntries = (_EX_CALLBACK_ROUTINE_BLOCK *)v6->Vm.Instance.VmWorkingSetList[9].LockedEntries,
(v36 = (INT64)LockedEntries) != 0) )
{
ExGetCallBackBlockRoutine(LockedEntries);
v18 = v16;
Mdl = (_MDL *)v17;
v19 = 512i64;
if( v7 > 0x200 / v16 )
{
if( v7 <= 0xC0000 / v16 )
v19 = v7 * v16;
else
v19 = ~(v16 - 1) & 0xC0000;
while( v19 > 0x200 )
{
Mdl = IoAllocateMdl(0i64, (unsigned int)((_DWORD)v19 << 12), 0, 0, v17);
v17 = 0i64;
if( Mdl )
break;
v19 = ~(v18 - 1) & (v18 + (v19 >> 1) - 1);
}
}
if( !Mdl )
{
Mdl = (_MDL *)v46;
v19 = 512i64;
}
v20 = v19 / v18;
while( 1 )
{
if( v7 < v20 )
v20 = v7;
v43 = v20;
Mdl->Next = (_MDL *)v17;
Mdl->Size = 8 * ((((v20 << 12) + 4095) >> 12) + 6);
Mdl->MdlFlags = (__int16)v17;
Mdl->StartVa = v17;
Mdl->ByteOffset = (unsigned int)v17;
Mdl->ByteCount = (_DWORD)v20 << 12;
v5 &= ~1u;
v21 = Mdl + 1;
if( (_BYTE)v34 == (_BYTE)v17 )
{
memmove(v21, Src, 8 * v20);
}
else
{
v15 = MiCaptureUlongPtrArray(v21, Src, v20, (INT64)&Mdl[1], (INT64)Irp, v33, v34, (INT64)PROCESS);
if( v15 < 0 )
goto LABEL_55;
}
v22 = Thread;
if( Thread->Tcb.ApcState.Process != v14 )
{
KeStackAttachProcess(&v14->Pcb, &ApcState);
v5 |= 1u;
}
if( !v13 )
{
LOCK_ADDRESS_SPACE(v22, v14);
if( (v14->Flags & 0x20) != 0 )
break;
}
v15 = MiFreePhysicalPages(v36, (INT64)Mdl);
HIDWORD(v34) = v15;
ByteOffset = Mdl->ByteOffset;
v42 = ByteOffset;
v17 = 0i64;
if( ByteOffset )
{
if( !v13 )
MiReturnProcessCommitment(v14, v18 * (unsigned int)ByteOffset);
v40 += ByteOffset;
}
if( !v13 )
{
UNLOCK_ADDRESS_SPACE(Thread, v14);
v17 = 0i64;
}
if( Mdl->ByteCount )
{
LODWORD(v24) = MiGetAweInfoPartition(v36);
v26 = -(__int64)(v18 * v25);
_InterlockedExchangeAdd64((volatile signed __int64 *)(v24 + 7608), v26);
v13 = Section;
if( !Section )
{
_InterlockedExchangeAdd64((volatile signed __int64 *)&PROCESS->VadPhysicalPages, v26);
v13 = Section;
}
Mdl->MdlFlags |= 2u;
Mdl->ByteCount <<= 12;
MiPreparePhysicalPagesMdlForFree((INT64)Mdl, v18);
MiFreePagesFromMdl(Mdl, 0i64, v27);
v7 = v39;
v14 = PROCESS;
v17 = 0i64;
}
v7 -= v42;
v39 = v7;
if( v15 || !v7 )
goto LABEL_55;
if( (v5 & 1) != 0 )
{
KeUnstackDetachProcess(&ApcState);
v5 &= ~1u;
v17 = 0i64;
}
WoW64Process = v14->WoW64Process;
if( WoW64Process && ((Machine = WoW64Process->Machine, Machine == 332) || Machine == 452) )
v30 = 4i64;
else
v30 = 8i64;
v20 = v43;
Src = (char *)Src + v43 * v30;
}
UNLOCK_ADDRESS_SPACE(v22, v14);
v15 = -1073741558;
}
else
{
v15 = -1073741585;
}
LABEL_55:
if( Mdl != (_MDL *)v46 )
{
Mdl->MdlFlags &= ~2u;
IoFreeMdl(Mdl);
}
if( (v5 & 1) != 0 )
KeUnstackDetachProcess(&ApcState);
if( (v5 & 4) == 0 )
{
v31 = v13;
if( !v13 )
v31 = v14;
ObfDereferenceObjectWithTag(v31, 0x68506D4Dui64);
}
*v44 = v40;
return v15;
}
return result;
}Referenced by:
No references.