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.