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.