NtUnlockVirtualMemory

NTSTATUS __stdcall NtUnlockVirtualMemory(VOID *ProcessHandle, VOID **BaseAddress, UINT64 *RegionSize, UINT64 MapType){
  _MMPTE *v5; 
  NTSTATUS result; 
  NTSTATUS v7; 
  unsigned __int64 v8; 
  int v9; 
  unsigned __int64 v10; 
  UINT64 v11; 
  INT64 j; 
  VOID *v13; 
  _EPROCESS *v14; 
  UINT64 v15; 
  _MMSUPPORT_INSTANCE *p_Instance; 
  unsigned __int8 v17; 
  _MMPTE *PteBase; 
  _MMPTE *PdeBase; 
  int v20; 
  INT64 v21; 
  _QWORD **v22; 
  _QWORD *i; 
  _MMPTE *v24; 
  _MMPTE *v25; 
  _MMPTE *v26; 
  INT64 v27; 
  unsigned __int64 v28; 
  _MMPFN *v29; 
  __int64 Blink; 
  _MMPTE *v31; 
  __int64 bf_0; 
  INT64 v33; 
  UINT64 v34; 
  unsigned __int64 v35; 
  INT64 m; 
  UINT64 v37; 
  INT64 v38; 
  _QWORD **v39; 
  _QWORD *k; 
  INT64 *v41; 
  int v42; 
  _EPROCESS *v43; 
  VOID *v44; 
  unsigned __int8 v45; 
  NTSTATUS v46; 
  char v47; 
  UINT64 OutCapturedRegionSize; 
  _EPROCESS *PROCESS; 
  VOID *StartingVa; 
  INT64 v51; 
  INT64 *v52; 
  unsigned __int64 v53; 
  UINT64 NumberOfVads; 
  VOID *VirtualAddress; 
  UINT64 *v56; 
  VOID **v57; 
  char WsleFlushList[144]; 
  __int128 v59; 
  __int128 v60; 
  __int64 v61; 
  _KAPC_STATE ApcState; 

  v56 = RegionSize;
  v57 = BaseAddress;
  v5 = 0i64;
  OutCapturedRegionSize = 0i64;
  StartingVa = 0i64;
  PROCESS = 0i64;
  memset(&ApcState, 0, sizeof(ApcState));
  *(_WORD *)&WsleFlushList[6] = 0;
  memset(&WsleFlushList[32], 0, 112);
  v59 = 0i64;
  v60 = 0i64;
  v61 = 0i64;
  result = MiLockUnlockCommon(
             ProcessHandle,
             BaseAddress,
             (VOID **)RegionSize,
             MapType,
             &StartingVa,
             &OutCapturedRegionSize,
             (VOID **)&PROCESS);
  v7 = result;
  v46 = result;
  if( result < 0 )
    return result;
  v8 = 0i64;
  v53 = 0i64;
  v9 = 0;
  v47 = 0;
  v10 = ((unsigned __int64)StartingVa + OutCapturedRegionSize - 1) & 0xFFFFFFFFFFFFF000ui64;
  OutCapturedRegionSize = v10;
  VirtualAddress = (VOID *)((unsigned __int64)StartingVa & 0xFFFFFFFFFFFFF000ui64);
  v11 = (unsigned __int64)StartingVa & 0xFFFFFFFFFFFFF000ui64;
  if( ProcessHandle != (VOID *)-1i64 )
  {
    KeStackAttachProcess(&PROCESS->Pcb, &ApcState);
    v9 = 2;
    v47 = 2;
  }
  *(_QWORD *)&WsleFlushList[8] = 20i64;
  *(_DWORD *)WsleFlushList = 1;
  *(_WORD *)&WsleFlushList[4] = 4;
  *(_QWORD *)&WsleFlushList[16] = 0i64;
  *(_QWORD *)&WsleFlushList[24] = 0i64;
  j = 0i64;
  v13 = (VOID *)v10;
  v14 = PROCESS;
  LODWORD(v15) = MiLockVadRange(PROCESS, (VOID *)v11, v13);
  NumberOfVads = v15;
  if( !v15 )
    goto LABEL_91;
  p_Instance = &v14->Vm.Instance;
  MiLockWorkingSetShared();
  v45 = v17;
  if( v11 <= OutCapturedRegionSize )
  {
    PteBase = MmGetPteBase();
    PdeBase = MmGetPdeBase();
    while( 1 )
    {
      if( (((unsigned __int8)(v11 >> 12) + 1) & 0xF) == 0 )
      {
        LOBYTE(v20) = MiWorkingSetIsContended((INT64)p_Instance);
        if( v20
          || v5 && (unsigned int)MiPageTableLockIsContended((__int64)p_Instance, (UINT64)v5)
          || MiShouldYieldProcessor() )
        {
          if( *(_DWORD *)&WsleFlushList[12] )
            MiFreeWsleList(p_Instance, (_MMWSLE_FLUSH_LIST *)WsleFlushList, 0i64);
          if( v5 )
          {
            MiUnlockPageTable((INT64)p_Instance, (UINT64)v5);
            v5 = 0i64;
          }
          MiUnlockWorkingSetShared(p_Instance, v45);
          MiLockWorkingSetShared();
        }
        PdeBase = MmGetPdeBase();
        PteBase = MmGetPteBase();
      }
      if( v11 > v8 || !j )
      {
        if( j )
        {
          v21 = j;
          v22 = *(_QWORD ***)(j + 8);
          if( v22 )
          {
            j = *(_QWORD *)(j + 8);
            for( i = *v22; i; i = (_QWORD *)*i )
              j = (INT64)i;
          }
          else
          {
            for( j = *(_QWORD *)(j + 16) & 0xFFFFFFFFFFFFFFFCui64; j; j = *(_QWORD *)(j + 16) & 0xFFFFFFFFFFFFFFFCui64 )
            {
              if( *(_QWORD *)j == v21 )
                break;
              v21 = j;
            }
          }
        }
        else
        {
          j = (INT64)MiLocateAddress((VOID *)v11);
        }
        v9 &= ~4u;
        v47 = v9;
        if( (*(_DWORD *)(j + 48) & 0x70) == 64 )
        {
          v9 |= 4u;
          v47 = v9;
        }
        else if( !MiVadPagesTradable(j) )
        {
          goto LABEL_55;
        }
        v53 = (*(unsigned int *)(j + 28) | ((unsigned __int64)*(unsigned __int8 *)(j + 33) << 32)) << 12;
      }
      v24 = (_MMPTE *)((char *)PteBase + ((v11 >> 9) & 0x7FFFFFFFF8i64));
      v25 = (_MMPTE *)((char *)PdeBase + ((v11 >> 18) & 0x3FFFFFF8));
      if( v5 == v25 )
        break;
      if( v5 )
      {
        if( *(_DWORD *)&WsleFlushList[12] )
          MiFreeWsleList(p_Instance, (_MMWSLE_FLUSH_LIST *)WsleFlushList, 0i64);
        MiUnlockPageTable((INT64)p_Instance, (UINT64)v5);
      }
      v26 = MiLockLowestValidPageTable((INT64)p_Instance, (INT64 *)v24, &v52);
      v5 = v26;
      if( v26 == v25 )
        break;
      MiUnlockPageTable((INT64)p_Instance, (UINT64)v26);
      v5 = 0i64;
      PteBase = MmGetPteBase();
      v11 = (((((_QWORD)v25 << 25) - ((_QWORD)PteBase << 25) + 0x10000000i64) >> 16 << 25) - ((_QWORD)PteBase << 25)) >> 16;
      v7 = -1073741782;
      v46 = -1073741782;
LABEL_54:
      v8 = v53;
      PdeBase = MmGetPdeBase();
      if( v11 > OutCapturedRegionSize )
        goto LABEL_55;
    }
    LODWORD(v27) = MI_READ_PTE_LOCK_FREE((INT64)v24);
    v51 = v27;
    if( (v27 & 1) == 0 )
    {
      v7 = -1073741782;
      v46 = -1073741782;
LABEL_53:
      PteBase = MmGetPteBase();
      v11 += 4096i64;
      goto LABEL_54;
    }
    LODWORD(v28) = MI_READ_PTE_LOCK_FREE((INT64)&v51);
    v29 = &MmGetPfnDb()[(v28 >> 12) & 0xFFFFFFFFFi64];
    v51 = (INT64)v29;
    Blink = (__int64)v29->ListEntry.Blink;
    v31 = (_MMPTE *)(Blink | 0x8000000000000000ui64);
    v52 = (INT64 *)(Blink | 0x8000000000000000ui64);
    if( (v9 & 4) != 0 )
    {
      if( MiRotatedToFrameBuffer(v24) == 1 )
      {
LABEL_52:
        v7 = v46;
        goto LABEL_53;
      }
      v29 = (_MMPFN *)v51;
      v31 = (_MMPTE *)v52;
    }
    bf_0 = v29->u4._bf_0;
    v33 = 0x1000000000i64;
    if( (bf_0 & 0x1000000000i64) == 0 && Blink > 0 )
      MiDemoteCombinedPte(p_Instance, v24, v31);
    if( (MiGetWsleContents(v33, v11) & 0xF) != 8 )
    {
      MiInsertTbFlushEntry((_MI_TB_FLUSH_LIST *)WsleFlushList, (VOID *)v11, 1ui64, 0i64);
      if( *(_DWORD *)&WsleFlushList[12] == *(_DWORD *)&WsleFlushList[8] )
        MiFreeWsleList(p_Instance, (_MMWSLE_FLUSH_LIST *)WsleFlushList, 0i64);
      v7 = -1073741782;
      v46 = -1073741782;
      goto LABEL_53;
    }
    goto LABEL_52;
  }
LABEL_55:
  if( *(_DWORD *)&WsleFlushList[12] )
    MiFreeWsleList(p_Instance, (_MMWSLE_FLUSH_LIST *)WsleFlushList, 0i64);
  if( v5 )
  {
    MiUnlockPageTable((INT64)p_Instance, (UINT64)v5);
    v5 = 0i64;
  }
  if( v7 == -1073741782 )
  {
    MiUnlockWorkingSetShared(p_Instance, v45);
    v14 = PROCESS;
    v15 = NumberOfVads;
LABEL_91:
    MiUnlockVadRange(v14, StartingVa, v15);
    if( (v9 & 2) != 0 )
      KeUnstackDetachProcess(&ApcState);
    ObfDereferenceObjectWithTag(v14, 0x6D566D4Dui64);
    return -1073741782;
  }
  v34 = (UINT64)VirtualAddress;
  v35 = 0i64;
  m = 0i64;
  v37 = OutCapturedRegionSize;
  if( (unsigned __int64)VirtualAddress > OutCapturedRegionSize )
    goto LABEL_86;
  do
  {
    if( v34 <= v35 && m )
      goto LABEL_75;
    if( m )
    {
      v38 = m;
      v39 = *(_QWORD ***)(m + 8);
      if( v39 )
      {
        m = *(_QWORD *)(m + 8);
        for( k = *v39; k; k = (_QWORD *)*k )
          m = (INT64)k;
      }
      else
      {
        for( m = *(_QWORD *)(m + 16) & 0xFFFFFFFFFFFFFFFCui64; m; m = *(_QWORD *)(m + 16) & 0xFFFFFFFFFFFFFFFCui64 )
        {
          if( *(_QWORD *)m == v38 )
            break;
          v38 = m;
        }
      }
    }
    else
    {
      m = (INT64)MiLocateAddress((VOID *)v34);
    }
    if( !MiVadPagesTradable(m) )
      break;
    v35 = (*(unsigned int *)(m + 28) | ((unsigned __int64)*(unsigned __int8 *)(m + 33) << 32)) << 12;
LABEL_75:
    v41 = (INT64 *)((char *)MmGetPteBase() + ((v34 >> 9) & 0x7FFFFFFFF8i64));
    if( v5 != (_MMPTE *)((char *)MmGetPdeBase() + ((v34 >> 18) & 0x3FFFFFF8)) )
    {
      if( v5 )
        MiUnlockPageTable((INT64)p_Instance, (UINT64)v5);
      v5 = MiLockLowestValidPageTable((INT64)p_Instance, v41, &v52);
    }
    MiUnlockVa(p_Instance, (VOID *)v34);
    v34 += 4096i64;
    if( (v34 & 0xF000) == 0 )
    {
      LOBYTE(v42) = MiWorkingSetIsContended((INT64)p_Instance);
      if( v42 || (unsigned int)MiPageTableLockIsContended((__int64)p_Instance, (UINT64)v5) || MiShouldYieldProcessor() )
      {
        MiUnlockPageTable((INT64)p_Instance, (UINT64)v5);
        v5 = 0i64;
        MiUnlockWorkingSetShared(p_Instance, v45);
        MiLockWorkingSetShared();
      }
    }
    v37 = OutCapturedRegionSize;
  }
  while( v34 <= OutCapturedRegionSize );
  LOBYTE(v9) = v47;
LABEL_86:
  if( v5 )
    MiUnlockPageTable((INT64)p_Instance, (UINT64)v5);
  MiUnlockWorkingSetShared(p_Instance, v45);
  v43 = PROCESS;
  MiUnlockVadRange(PROCESS, StartingVa, NumberOfVads);
  if( (v9 & 2) != 0 )
    KeUnstackDetachProcess(&ApcState);
  ObfDereferenceObjectWithTag(v43, 0x6D566D4Dui64);
  v44 = VirtualAddress;
  *v56 = v37 - (_QWORD)VirtualAddress + 4096;
  *v57 = v44;
  return 0;
}

Referenced by:

No references.