VmpRemoveMemoryRange

NTSTATUS __fastcall VmpRemoveMemoryRange(INT64 *SpinLock, UINT64 a2, _RTL_BALANCED_NODE *a3, INT64 a4, INT64 a5){
  void *v5; 
  unsigned __int64 v9; 
  INT64 v10; 
  NTSTATUS v11; 
  unsigned __int64 v12; 
  UINT64 v13; 
  unsigned __int64 v14; 
  _RTL_BALANCED_NODE *v15; 
  UINT64 v16; 
  _QWORD *v18; 
  _QWORD *v19; 
  __int64 v20; 
  _QWORD *v21; 
  __int64 v22; 
  unsigned __int64 v23; 
  _RTL_BALANCED_NODE *v24; 
  unsigned __int64 v25; 
  unsigned __int64 v26; 
  bool v27; 
  INT64 v28; 
  INT64 a4a[2]; 
  __int64 v30; 
  _QWORD *v31; 
  INT64 a6; 
  __int64 v33; 
  PVOID P; 

  v5 = 0i64;
  v28 = 0i64;
  v31 = 0i64;
  v33 = (__int64)a3 + a4 - 1;
  P = 0i64;
  v9 = a4 + a2 - 1;
  LODWORD(v10) = VmpProcessContextLockExclusive(SpinLock);
  a6 = v10;
  if( SpinLock[9] != a5 )
  {
    v11 = -1073740007;
    goto LABEL_18;
  }
  v30 = 0i64;
  *(_OWORD *)a4a = 0i64;
  VmpFlushTbVaRange(SpinLock, a2, v9, (INT64)a4a, (INT64)&v28, (INT64)&a6);
  v12 = (unsigned __int64)(SpinLock + 1);
  v13 = SpinLock[1];
  if( (SpinLock[2] & 1) != 0 && v13 )
    v13 ^= v12;
  while( 1 )
  {
    if( !v13 )
      goto LABEL_16;
    v14 = *(_QWORD *)(v13 + 32);
    if( (unsigned __int64)a3 <= v14 )
      break;
    v16 = *(_QWORD *)(v13 + 8);
LABEL_11:
    if( (SpinLock[2] & 1) != 0 && v16 )
      v13 ^= v16;
    else
      v13 = v16;
  }
  v15 = *(_RTL_BALANCED_NODE **)(v13 + 24);
  if( a3 < v15 )
  {
    v16 = *(_QWORD *)v13;
    goto LABEL_11;
  }
  v18 = (_QWORD *)(v13 - 24);
  if( v13 == 24 )
  {
LABEL_16:
    v11 = -1073741172;
    goto LABEL_17;
  }
  v19 = (_QWORD *)v18[2];
  if( v15 != a3 || v14 != v33 || v19[3] != a2 || v19[4] != v9 )
  {
    LODWORD(v23) = VmpVaRangeNumberOfGpaRanges(v18[2]);
    if( v23 > 1 )
    {
LABEL_40:
      v11 = -1073741637;
      goto LABEL_17;
    }
    if( a3 == v24 && a2 == v19[3] )
    {
      v27 = v26 == v25;
      if( v26 >= v25 )
      {
LABEL_47:
        if( v27 && v9 == v19[4] && a3 > v24 && a2 > v19[3] )
        {
          v18[7] = (char *)a3 - 1;
          v19[4] = a2 - 1;
          goto LABEL_52;
        }
        goto LABEL_40;
      }
      if( v9 < v19[4] )
      {
        v18[6] = v26 + 1;
        v19[3] = v9 + 1;
        goto LABEL_52;
      }
    }
    v27 = v26 == v25;
    goto LABEL_47;
  }
  RtlRbRemoveNode((UINT64 *)SpinLock + 1, v13);
  v18[5] = -1i64;
  v20 = *v18;
  v21 = (_QWORD *)v18[1];
  if( *(_QWORD **)(*v18 + 8i64) != v18 || (_QWORD *)*v21 != v18 )
    __fastfail(3u);
  *v21 = v20;
  *(_QWORD *)(v20 + 8) = v21;
  P = v18;
  if( (_QWORD *)v19[5] == v19 + 5 )
  {
    RtlRbRemoveNode((UINT64 *)SpinLock + 3, (UINT64)v19);
    v19[2] = -1i64;
    v22 = *(_QWORD *)v12;
    v31 = v19;
    if( (SpinLock[2] & 1) == 0 )
      goto LABEL_36;
    if( !v22 )
      goto LABEL_37;
    v22 ^= v12;
LABEL_36:
    if( !v22 )
    {
LABEL_37:
      *((_DWORD *)SpinLock + 22) = 0;
      SpinLock[9] = -1i64;
    }
  }
LABEL_52:
  ++SpinLock[5];
  v11 = 0;
LABEL_17:
  v5 = v31;
LABEL_18:
  if( a6 != -1 )
  {
    ExReleaseSpinLockExclusiveFromDpcLevel(SpinLock);
    __writecr8((unsigned __int8)a6);
  }
  if( P )
    ExFreePoolWithTag(P, 0);
  if( v5 )
    VmpFreeMemoryRanges(v5);
  return v11;
}

Referenced by:

VmDeleteMemoryRange