NtMapUserPhysicalPagesScatter

NTSTATUS __stdcall NtMapUserPhysicalPagesScatter(VOID **VirtualAddresses, UINT64 NumberOfPages, UINT64 *UserPfnArray){
  INT64 v6; 
  _ETHREAD *CurrentThread; 
  UINT64 *Pool; 
  INT64 v10; 
  char *v11; 
  UINT64 *v12; 
  int v13; 
  INT64 v14; 
  UINT64 v15; 
  _MMPTE *AweNode; 
  _EX_CALLBACK_ROUTINE_BLOCK *Long; 
  union {unsigned __int64 Long;volatile unsigned __int64 VolatileLong;_MMPTE_HARDWARE Hard;_MMPTE_PROTOTYPE Proto;_MMPTE_SOFTWARE Soft;_MMPTE_TIMESTAMP TimeStamp;_MMPTE_TRANSITION Trans;_MMPTE_SUBSECTION Subsect;_MMPTE_LIST List;} v18; 
  __int64 v19; 
  __int64 v20; 
  int v21; 
  unsigned __int64 v22; 
  unsigned __int64 v23; 
  __int64 v24; 
  _MMPTE *v25; 
  int v26; 
  int v27; 
  VOID *v28; 
  VOID *v29; 
  INT64 v30; 
  INT64 *v31; 
  __int64 v32; 
  INT64 a5; 
  INT64 a5a; 
  INT64 a6; 
  INT64 a6a; 
  INT64 v37; 
  INT64 v38; 
  INT64 v39; 
  INT64 v40; 
  INT64 v41; 
  VOID *LockHandle; 
  INT64 v43[2]; 
  char Destination[4096]; 
  char v45; 

  memset(Destination, 0i64, sizeof(Destination));
  *(_OWORD *)v43 = 0i64;
  if( NumberOfPages > 0xFFFFFFFFFFFFFi64 )
    return -1073741584;
  CurrentThread = (_ETHREAD *)KeGetCurrentThread();
  Pool = (UINT64 *)Destination;
  v10 = 0i64;
  v11 = 0i64;
  if( NumberOfPages > 0x200 )
  {
    Pool = (UINT64 *)MiAllocatePool(
                       64i64,
                       NumberOfPages * ((((unsigned __int128)-(__int128)(unsigned __int64)UserPfnArray >> 64) & 8) + 8),
                       0x77526D4Dui64);
    if( !Pool )
      return -1073741670;
  }
  v12 = Pool;
  v13 = MiCaptureUlongPtrArray(Pool, VirtualAddresses, NumberOfPages, v6, a5, a6, v37, v39);
  if( v13 >= 0 )
  {
    if( !NumberOfPages )
      return 0;
    if( !UserPfnArray )
      goto LABEL_13;
    v11 = &v45;
    if( NumberOfPages > 0x200 )
      v11 = (char *)&Pool[NumberOfPages];
    v13 = MiCaptureUlongPtrArray(v11, UserPfnArray, NumberOfPages, v14, a5a, a6a, v38, v40);
    if( v13 >= 0 )
    {
LABEL_13:
      v15 = *Pool;
      v13 = 0;
      LockHandle = MiLockAweVadsShared(&CurrentThread->Tcb);
      AweNode = MiGetAweNode(v15);
      if( !AweNode || (AweNode[5].u.Long & 3) != 0 )
      {
        v13 = -1073741585;
      }
      else
      {
        Long = (_EX_CALLBACK_ROUTINE_BLOCK *)AweNode[4].u.Long;
        v41 = (INT64)AweNode;
        ExGetCallBackBlockRoutine(Long);
        v20 = v19;
        v21 = -1073741585;
        do
        {
          v22 = *v12;
          if( v20 == 1 )
          {
            v23 = *v12;
          }
          else
          {
            v24 = (v20 << 12) - 1;
            if( (v24 & v22) != 0 )
              goto LABEL_38;
            v23 = v24 + v22;
          }
          if( v22 < (*(unsigned int *)(v18.Long + 24) | ((unsigned __int64)*(unsigned __int8 *)(v18.Long + 32) << 32)) << 12
            || v23 > (((*(unsigned int *)(v18.Long + 28) | ((unsigned __int64)*(unsigned __int8 *)(v18.Long + 33) << 32)) << 12) | 0xFFF) )
          {
            v25 = MiGetAweNode(*v12);
            if( !v25 || (v25[5].u.Long & 3) != 0 || (_EX_CALLBACK_ROUTINE_BLOCK *)v25[4].u.Long != Long )
            {
LABEL_38:
              v10 = v41;
              v13 = v21;
              goto LABEL_39;
            }
            v18.Long = (unsigned __int64)v25[3].u;
            v27 = *(_DWORD *)(v18.Long + 48) & 0x1100000;
            if( v26 == 17825792 )
            {
              if( v27 != 17825792 )
                v13 = v21;
            }
            else if( v27 == 17825792 )
            {
              v13 = v21;
            }
          }
          ++v12;
        }
        while( v12 < &Pool[NumberOfPages] );
        LODWORD(v28) = MiLockAwePagesShared((INT64)Long, (INT64)CurrentThread);
        v29 = v28;
        if( v11
          && (v13 = MiReferenceIncomingPhysicalPages(
                      Long,
                      (INT64)v11,
                      NumberOfPages,
                      (INT64)Pool,
                      (INT64)v43,
                      v41,
                      0i64),
              v13 < 0) )
        {
          v10 = v41;
        }
        else
        {
          v10 = v41;
          LODWORD(v30) = MiWriteAwePtes(v41, (INT64)v11, NumberOfPages, (INT64)Pool, 0i64, 1);
          v43[1] = v30;
        }
        if( v29 )
          MiUnlockAweVadsShared(&CurrentThread->Tcb, v29);
      }
LABEL_39:
      if( LockHandle )
        MiUnlockAweVadsShared(&CurrentThread->Tcb, LockHandle);
    }
  }
  v31 = v43;
  v32 = 2i64;
  do
  {
    if( *v31 )
      MiFreePhysicalPageChain(v10, *v31, 0i64);
    ++v31;
    --v32;
  }
  while( v32 );
  if( Pool != (UINT64 *)Destination )
    ExFreePoolWithTag(Pool, 0);
  return v13;
}

Referenced by:

No references.