NtLockVirtualMemory

NTSTATUS __stdcall NtLockVirtualMemory(PVOID ProcessHandle, PVOID *BaseAddress, UINT64 *RegionSize, UINT64 MapType){
  int v5; 
  NTSTATUS result; 
  unsigned __int64 v7; 
  unsigned __int64 v8; 
  void *v9; 
  void *v10; 
  _MMPTE *PteBase; 
  unsigned __int64 v12; 
  NTSTATUS v13; 
  __int64 Address; 
  _QWORD *v15; 
  __int64 v16; 
  __int64 v17; 
  _QWORD *v18; 
  _QWORD **v19; 
  _QWORD *i; 
  char *v21; 
  _MMSUPPORT_INSTANCE *v22; 
  CHAR v23; 
  unsigned __int64 v24; 
  _MMPTE *PdeBase; 
  __int64 v26; 
  _QWORD **v27; 
  _QWORD *j; 
  unsigned __int64 v29; 
  ULONG_PTR v30; 
  char *v31; 
  UNICODE_STRING *v32; 
  UINT8 v33; 
  WCHAR *v34; 
  int v35; 
  _MMPFN *v36; 
  _MMPFN *PfnDb; 
  UNICODE_STRING *v38; 
  UINT8 v39; 
  WCHAR *v40; 
  int v41; 
  UINT64 v42; 
  __int64 v43; 
  int v44; 
  UINT64 v45; 
  UINT64 v46; 
  CHAR v47; 
  UINT64 v48; 
  UNICODE_STRING *v49; 
  UINT8 v50; 
  PWCHAR v51; 
  int v52; 
  UINT64 v53; 
  unsigned __int64 v54; 
  ULONG_PTR v55; 
  unsigned __int64 v56; 
  char *v57; 
  int v58; 
  INT64 v59; 
  INT64 v60; 
  int v61; 
  char v62; 
  int v63; 
  INT64 v64; 
  INT64 v65; 
  int v66; 
  bool v67; 
  unsigned __int64 v68; 
  __int64 v69; 
  _DWORD *a6; 
  CHAR v71; 
  CHAR a4; 
  int v73; 
  NTSTATUS v74; 
  unsigned __int64 v75; 
  _QWORD *v76; 
  unsigned __int64 v77; 
  char v78; 
  unsigned __int64 v79; 
  PVOID Object; 
  ULONG_PTR BugCheckParameter2; 
  int v82; 
  ULONG_PTR BugCheckParameter1; 
  PVOID P; 
  int v85; 
  unsigned __int64 v86; 
  PVOID StartingVa; 
  unsigned __int64 v88; 
  char *v89; 
  __int64 v90; 
  UINT64 NumberOfVads; 
  INT64 a2; 
  INT64 a1; 
  INT64 v94; 
  _ETHREAD *Thread; 
  UINT64 *v96; 
  PVOID *v97; 
  struct _KAPC_STATE ApcState; 
  v96 = RegionSize;
  v97 = BaseAddress;
  memset(&ApcState, 0, sizeof(ApcState));
  v90 = 0i64;
  v88 = 0i64;
  Object = 0i64;
  v85 = 0;
  v5 = 0;
  v78 = 0;
  v82 = 0;
  result = MiLockUnlockCommon(
             ProcessHandle,
             BaseAddress,
             (PVOID *)RegionSize,
             MapType,
             (__int64)&v88,
             (__int64)&v90,
             (__int64)&Object);
  if( result < 0 )
    return result;
  Thread = (_ETHREAD *)KeGetCurrentThread();
  v7 = v88;
  v8 = (v88 + v90 - 1) & 0xFFFFFFFFFFFFF000ui64;
  v86 = v8;
  v9 = (void *)(v88 & 0xFFFFFFFFFFFFF000ui64);
  v79 = v88 & 0xFFFFFFFFFFFFF000ui64;
  v75 = 0i64;
  LODWORD(v10) = MiAllocatePool((struct _SLIST_ENTRY *)0x40);
  P = v10;
  if( !v10 )
  {
    ObfDereferenceObjectWithTag(Object, 0x6D566D4Dui64);
    return -1073741670;
  }
  if( ProcessHandle != (PVOID)-1i64 )
  {
    KeStackAttachProcess((PRKPROCESS)Object, &ApcState);
    v5 = 2;
    v78 = 2;
    v82 = 2;
  }
  PteBase = MmGetPteBase();
  BugCheckParameter1 = (ULONG_PTR)PteBase + ((v7 >> 9) & 0x7FFFFFFFF8i64);
  StartingVa = v9;
  a2 = (INT64)PteBase + ((v8 >> 9) & 0x7FFFFFFFF8i64);
  v12 = MiLockVadRange((__int64)Object, (unsigned __int64)v9, v8, 0);
  NumberOfVads = v12;
  if( !v12 )
  {
    v13 = -1073741819;
LABEL_90:
    MiUnlockVadRange((_EPROCESS *)Object, StartingVa, v12);
    if( (v5 & 2) != 0 )
      KeUnstackDetachProcess(&ApcState);
    ObfDereferenceObjectWithTag(Object, 0x6D566D4Dui64);
    ExFreePoolWithTag(P, 0);
    return v13;
  }
  Address = (__int64)MiLocateAddress((UINT64)v9);
  v76 = (_QWORD *)Address;
  v15 = (_QWORD *)Address;
  if( v16 )
  {
    while( (unsigned int)MiVadPagesTradable((INT64)v15) )
    {
      v18 = v15;
      v19 = (_QWORD **)v15[1];
      if( v19 )
      {
        v15 = (_QWORD *)v15[1];
        for( i = *v19; i; i = (_QWORD *)*i )
          v15 = i;
      }
      else
      {
        while( 1 )
        {
          v15 = (_QWORD *)(v15[2] & 0xFFFFFFFFFFFFFFFCui64);
          if( !v15 || (_QWORD *)*v15 == v18 )
            break;
          v18 = v15;
        }
      }
      if( v17 + 1 >= v12 )
        goto LABEL_18;
    }
    v13 = -1073741747;
    goto LABEL_90;
  }
LABEL_18:
  v73 = MiVadPureReserve(Address);
  v21 = 0i64;
  v22 = (_MMSUPPORT_INSTANCE *)((char *)Object + 1664);
  a1 = (INT64)Object + 1664;
  v89 = (char *)*((_QWORD *)Object + 210);
LABEL_19:
  a4 = MiLockWorkingSetShared((INT64)v22);
  v23 = a4;
LABEL_20:
  v24 = v79;
  PdeBase = MmGetPdeBase();
  while( v24 <= v8 )
  {
    if( v24 >> 12 > (*(unsigned int *)(Address + 28) | ((unsigned __int64)*(unsigned __int8 *)(Address + 33) << 32)) )
    {
      v26 = Address;
      v27 = *(_QWORD ***)(Address + 8);
      if( v27 )
      {
        Address = *(_QWORD *)(Address + 8);
        v76 = v27;
        for( j = *v27; j; j = (_QWORD *)*j )
        {
          Address = (__int64)j;
          v76 = j;
        }
      }
      else
      {
        Address = *(_QWORD *)(Address + 16) & 0xFFFFFFFFFFFFFFFCui64;
        v76 = (_QWORD *)Address;
        if( Address )
        {
          do
          {
            if( *(_QWORD *)Address == v26 )
              break;
            v26 = Address;
            Address = *(_QWORD *)(Address + 16) & 0xFFFFFFFFFFFFFFFCui64;
          }
          while( Address );
          v76 = (_QWORD *)Address;
        }
      }
      v73 = MiVadPureReserve(Address);
    }
    BugCheckParameter2 = (ULONG_PTR)PdeBase + ((v24 >> 18) & 0x3FFFFFF8);
    if( v21 != (char *)BugCheckParameter2 )
    {
      if( v21 )
      {
        MiUnlockPageTable((INT64)v22, (UINT64)v21);
        v21 = 0i64;
        v23 = a4;
      }
      if( v73 )
      {
        MiGetNextPageTable(BugCheckParameter1, a2, 0i64, v23, 0, &v85);
        if( v29 )
          v21 = (char *)MmGetPteBase() + ((v29 >> 9) & 0x7FFFFFFFF8i64);
        if( v29 != BugCheckParameter1 )
        {
          v13 = -1073741819;
          goto LABEL_64;
        }
      }
      else
      {
        v30 = BugCheckParameter1;
        MiMakeSystemAddressValid(BugCheckParameter1, 0i64, (*(_DWORD *)(Address + 48) >> 12) & 0x3F, v23, 0);
        v21 = (char *)MmGetPteBase() + ((v30 >> 9) & 0x7FFFFFFFF8i64);
      }
    }
    if( (*(_BYTE *)BugCheckParameter1 & 1) == 0 )
    {
      MiUnlockPageTable((INT64)v22, (UINT64)v21);
      v21 = 0i64;
      BugCheckParameter2 = 0i64;
      MiUnlockWorkingSetShared((INT64)v22, a4);
      goto LABEL_19;
    }
    v94 = MI_READ_PTE_LOCK_FREE(BugCheckParameter1);
    v31 = (char *)MmGetPfnDb() + 48 * (((unsigned __int64)MI_READ_PTE_LOCK_FREE((INT64)&v94) >> 12) & 0xFFFFFFFFFi64);
    if( (MiGetWsleContents(0xFFFFFFFFFi64, v79) & 0xF) == 8 )
    {
      v5 |= 1u;
      v78 = v5;
      v82 = v5;
    }
    else
    {
      if( v22->MinimumWorkingSetSize <= *((_QWORD *)v89 + 4) + 6i64 )
      {
        v13 = -1073741663;
        goto LABEL_64;
      }
      LOBYTE(v35) = MI_PFN_IS_PROTO((UNICODE_STRING *)v31, v32, v33, v34);
      if( v35 && !(unsigned int)MiLockPageTablePage(v36, 1i64) )
        goto LABEL_63;
      PfnDb = MmGetPfnDb();
      BugCheckParameter2 = (ULONG_PTR)PfnDb
                         + 48 * (((unsigned __int64)MI_READ_PTE_LOCK_FREE(BugCheckParameter2) >> 12) & 0xFFFFFFFFFi64);
      if( !(unsigned int)MiLockPageTablePage((_MMPFN *)BugCheckParameter2, 2i64) )
      {
        LOBYTE(v41) = MI_PFN_IS_PROTO((UNICODE_STRING *)v31, v38, v39, v40);
        if( v41 )
          MiUnlockPageTableCharges((_MMPFN *)((char *)PfnDb + 48 * (*((_QWORD *)v31 + 5) & 0xFFFFFFFFFi64)), 1u, v42);
        goto LABEL_63;
      }
      v43 = 0i64;
      if( (*((_DWORD *)v31 + 4) & 0x400i64) != 0 )
      {
        LOBYTE(v44) = MI_PFN_IS_PROTO((UNICODE_STRING *)v31, v38, v39, v40);
        if( v44 )
        {
          v43 = *(_QWORD *)(qword_140C4E388 + 8 * ((*((_QWORD *)v31 + 5) >> 39) & 0x3FFi64));
          if( !(unsigned int)MiChargeCommit((_MI_PARTITION *)v43, 1ui64, 0i64) )
          {
            MiUnlockPageTableCharges((_MMPFN *)BugCheckParameter2, 2u, v45);
            MiUnlockPageTableCharges(
              (_MMPFN *)((char *)MmGetPfnDb() + 48 * (*((_QWORD *)v31 + 5) & 0xFFFFFFFFFi64)),
              1u,
              v46);
            v13 = -1073741523;
            goto LABEL_64;
          }
          _InterlockedAdd64((volatile signed __int64 *)(v43 + 7616), 1ui64);
        }
      }
      else if( (unsigned int)MiGetPagingFileOffset((MMPTE *)(v31 + 16)) )
      {
        MiLockPageAndSetDirty((INT64)v31, 1i64);
      }
      if( !MiLockWsle((INT64)v22, v79) )
      {
        MiUnlockPageTableCharges((_MMPFN *)BugCheckParameter2, 2u, v48);
        LOBYTE(v52) = MI_PFN_IS_PROTO((UNICODE_STRING *)v31, v49, v50, v51);
        if( v52 )
        {
          MiUnlockPageTableCharges(
            (_MMPFN *)((char *)MmGetPfnDb() + 48 * (*((_QWORD *)v31 + 5) & 0xFFFFFFFFFi64)),
            1u,
            v53);
          if( (*((_DWORD *)v31 + 4) & 0x400i64) != 0 )
            MiReturnCommit((_MI_PARTITION *)v43, 1ui64);
        }
LABEL_63:
        v13 = -1073741670;
LABEL_64:
        v74 = v13;
        if( v21 )
        {
          MiUnlockPageTable((INT64)v22, (UINT64)v21);
          v21 = 0i64;
        }
        if( !v75 )
        {
LABEL_87:
          if( v21 )
            MiUnlockPageTable((INT64)v22, (UINT64)v21);
          MiUnlockWorkingSetShared((INT64)v22, a4);
          v12 = NumberOfVads;
          goto LABEL_90;
        }
        v54 = v75 - 1;
        v77 = v75 - 1;
        v55 = (ULONG_PTR)StartingVa + 4096 * v75 - 4096;
        BugCheckParameter2 = v55;
        v56 = v75;
        while( 2 )
        {
          if( _bittest64((const signed __int64 *)P, v54) == 1 )
          {
            v57 = (char *)MmGetPdeBase() + ((v55 >> 18) & 0x3FFFFFF8);
            v89 = v57;
            if( v21 != v57 )
            {
              if( v21 )
              {
                MiUnlockPageTable((INT64)v22, (UINT64)v21);
                v57 = v89;
              }
              v21 = v57;
              MiLockPageTable((INT64)v22, (UINT64)v57);
            }
            MiUnlockVa(v22, (PVOID)v55);
            v54 = v77;
          }
          v58 = 0;
          if( (v54 & 0xF) != 0 )
          {
LABEL_81:
            if( v58 == 1 )
              goto LABEL_82;
          }
          else
          {
            if( !MiWorkingSetIsContended((INT64)v22) )
            {
              if( !v21 || (MiPageTableLockIsContended((INT64)v22, (UINT64)v21, v59, v60, v69, (INT64)a6, v71), !v61) )
              {
                if( MiShouldYieldProcessor() )
                  v58 = 1;
                v54 = v77;
                goto LABEL_81;
              }
            }
LABEL_82:
            if( v21 )
            {
              MiUnlockPageTable((INT64)v22, (UINT64)v21);
              v21 = 0i64;
            }
            MiUnlockWorkingSetShared((INT64)v22, a4);
            MiLockWorkingSetShared((INT64)v22);
            v54 = v77;
          }
          v55 = BugCheckParameter2 - 4096;
          BugCheckParameter2 -= 4096i64;
          v77 = --v54;
          if( !--v56 )
          {
            LOBYTE(v5) = v78;
            v13 = v74;
            goto LABEL_87;
          }
          continue;
        }
      }
      MiGetEffectivePagePriorityThread(Thread, v47, v48);
      MiLockPageAtDpc((INT64)v31);
      MiUpdatePfnPriority((INT64)v31);
      _InterlockedAnd64((volatile signed __int64 *)v31 + 3, 0x7FFFFFFFFFFFFFFFui64);
      _bittestandset64((signed __int64 *)P, v75);
      Address = (__int64)v76;
    }
    ++v75;
    v62 = BugCheckParameter1 + 8;
    BugCheckParameter1 += 8i64;
    v24 = v79 + 4096;
    v79 = v24;
    v63 = 0;
    if( v24 <= v86 && (v62 & 0x78) == 0 )
    {
      if( MiWorkingSetIsContended((INT64)v22)
        || (MiPageTableLockIsContended((INT64)v22, (UINT64)v21, v64, v65, v69, (INT64)a6, v71), v66) )
      {
LABEL_103:
        MiUnlockPageTable((INT64)v22, (UINT64)v21);
        MiUnlockWorkingSetShared((INT64)v22, a4);
        v21 = 0i64;
        MiLockWorkingSetShared((INT64)v22);
        v8 = v86;
        v23 = a4;
        goto LABEL_20;
      }
      if( MiShouldYieldProcessor() )
        v63 = 1;
      v24 = v79;
    }
    v67 = v63 == 0;
    v8 = v86;
    v23 = a4;
    PdeBase = MmGetPdeBase();
    if( !v67 )
      goto LABEL_103;
  }
  if( v21 )
  {
    MiUnlockPageTable((INT64)v22, (UINT64)v21);
    v23 = a4;
  }
  MiUnlockWorkingSetShared((INT64)v22, v23);
  MiUnlockVadRange((_EPROCESS *)Object, StartingVa, NumberOfVads);
  if( (v5 & 2) != 0 )
    KeUnstackDetachProcess(&ApcState);
  ObfDereferenceObjectWithTag(Object, 0x6D566D4Dui64);
  ExFreePoolWithTag(P, 0);
  v68 = v88 & 0xFFFFFFFFFFFFF000ui64;
  *v96 = v8 - (v88 & 0xFFFFFFFFFFFFF000ui64) + 4096;
  *v97 = (PVOID)v68;
  return(v5 & 1) != 0 ? 0x40000019 : 0;
}

Referenced by:

No references.