MiObtainSessionVa

VOID *__stdcall MiObtainSessionVa(UINT64 NumberOfRegions){
  UINT64 v1; 
  _MM_SESSION_SPACE *Session; 
  UINT64 v3; 
  _RTL_BITMAP_EX *v4; 
  UINT64 v5; 
  __int64 v6; 
  unsigned __int64 v7; 
  UINT64 v8; 
  unsigned __int64 v9; 
  unsigned __int64 v10; 
  unsigned __int64 *v11; 
  __int64 v12; 
  unsigned int v13; 
  unsigned __int64 v14; 
  unsigned __int64 v15; 
  unsigned __int64 v16; 
  _ETHREAD *CurrentThread; 
  UINT64 ClearBitsAndSet; 
  UINT64 v19; 
  _ETHREAD *v20; 
  unsigned int v21; 
  unsigned __int8 v22; 
  int v23; 
  bool v24; 
  __int64 v25; 
  _KLOCK_ENTRY *v26; 
  __int64 v27; 
  __int64 v29; 
  unsigned __int64 v30; 
  unsigned __int64 v31; 
  unsigned int v32; 
  unsigned __int64 *v33; 
  __int64 v34; 
  unsigned int v35; 
  unsigned __int64 v36; 
  unsigned __int64 v37; 
  __int64 v38; 
  unsigned __int64 v39; 
  __int64 v40; 
  unsigned int v41; 
  __int64 v42; 
  unsigned __int64 *v43; 
  unsigned int v44; 
  __int64 v45; 
  __int64 v46; 
  UINT64 v47; 
  UINT64 v48; 
  _ETHREAD *v49; 
  unsigned int SessionId; 
  unsigned __int8 v51; 
  int v52; 
  __int64 v53; 
  _KLOCK_ENTRY *v54; 
  __int64 v55; 
  UINT64 v56; 
  UINT64 v57; 
  UINT64 a3; 
  unsigned int v59; 
  int v60; 
  unsigned int v61; 
  int v62; 
  int v63; 
  unsigned int v64; 
  _MM_SESSION_SPACE *v65; 
  UINT64 v66; 
  int v67; 

  v1 = (unsigned int)NumberOfRegions;
  Session = KeGetCurrentThread()->ApcState.Process->Session;
  v65 = Session;
  v4 = (_RTL_BITMAP_EX *)((char *)Session + 832);
  v5 = *((_QWORD *)Session + 104);
  v6 = *((_QWORD *)Session + 105);
  v57 = *((_QWORD *)Session + 106);
  v3 = v57;
  v56 = v5;
  v7 = v3 & -(__int64)(v3 < v5);
  v8 = v5 - 1;
  if( (_DWORD)v1 )
  {
    while( v8 - v7 + 1 < v1 )
    {
      v15 = -1i64;
LABEL_102:
      if( !v7 )
        goto LABEL_12;
      v47 = v1 + v3;
      if( v1 + v3 > v5 )
        v47 = v5;
      v8 = v47 - 1;
      v7 = 0i64;
    }
    v9 = v8 - v1 + 1;
    v10 = v6 + 8 * (v9 >> 6);
    v11 = (unsigned __int64 *)(v6 + 8 * (v7 >> 6));
    v12 = *v11 | ((1i64 << (v7 & 0x3F)) - 1);
    if( v1 > 0x7F )
    {
      v39 = v10 + 8;
      if( (v9 & 0x3F) == 0 )
        v39 = v6 + 8 * ((v8 - v1 + 1) >> 6);
      if( v12 )
      {
        if( *++v11 )
          goto LABEL_77;
        HIDWORD(a3) = 0;
        v24 = !_BitScanReverse64((unsigned __int64 *)&v40, v12);
        if( v24 )
          v41 = 64;
        else
          v41 = 63 - v40;
        HIDWORD(a3) = v41;
      }
      else
      {
        v41 = 0;
      }
LABEL_82:
      v15 = (((__int64)v11 - v6) >> 3 << 6) - v41;
      if( v15 > v9 )
      {
LABEL_42:
        v15 = -1i64;
LABEL_43:
        v3 = v57;
        v5 = v56;
        goto LABEL_102;
      }
      v43 = &v11[(v1 - v41) >> 6];
      while( ++v11 != v43 )
      {
        if( *v11 )
          goto LABEL_77;
      }
      v44 = ((_BYTE)v1 - (_BYTE)v41) & 0x3F;
      if( (((_BYTE)v1 - (_BYTE)v41) & 0x3F) != 0 )
      {
        v24 = !_BitScanForward64((unsigned __int64 *)&v45, *v11);
        if( v24 )
          LODWORD(v45) = 64;
        v60 = v45;
        if( (unsigned int)v45 < v44 )
        {
LABEL_77:
          while( (unsigned __int64)v11 <= v39 )
          {
            if( !*++v11 )
            {
              v59 = 0;
              v24 = !_BitScanReverse64((unsigned __int64 *)&v42, *(v11 - 1));
              if( v24 )
                v41 = 64;
              else
                v41 = 63 - v42;
              v59 = v41;
              goto LABEL_82;
            }
          }
LABEL_41:
          v15 = -1i64;
          goto LABEL_43;
        }
      }
LABEL_11:
      if( v15 != -1i64 )
      {
LABEL_12:
        Session = v65;
        v16 = v15;
        v4 = (_RTL_BITMAP_EX *)((char *)v65 + 832);
        goto LABEL_13;
      }
      goto LABEL_43;
    }
    v13 = 64;
    if( v1 < 0x40 )
    {
      if( v1 <= 1 )
      {
        while( 1 )
        {
          if( v12 != -1 )
          {
            _BitScanForward64(&v14, ~v12);
            v15 = v14 + (((__int64)v11 - v6) >> 3 << 6);
            goto LABEL_10;
          }
          if( (unsigned __int64)++v11 > v10 )
            break;
          v12 = *v11;
        }
        v15 = -1i64;
        goto LABEL_43;
      }
      v32 = 0;
      v33 = (unsigned __int64 *)(v6 + 8 * (v8 >> 6));
      while( 1 )
      {
        if( v12 == -1 )
        {
          while( 1 )
          {
            if( (unsigned __int64)++v11 > v10 )
              goto LABEL_42;
            v12 = *v11;
            if( *v11 != -1i64 )
            {
              v32 = 0;
              break;
            }
          }
        }
        v24 = !_BitScanForward64((unsigned __int64 *)&v34, v12);
        if( v24 )
          LODWORD(v34) = 64;
        v63 = v34;
        if( v32 + (unsigned int)v34 >= v1 )
          break;
        v35 = v1;
        v36 = ~v12;
        while( 1 )
        {
          v36 &= v36 >> (v35 >> 1);
          if( !v36 )
            break;
          v35 -= v35 >> 1;
          if( v35 <= 1 )
          {
            _BitScanForward64(&v37, v36);
            v38 = (unsigned int)v37;
            goto LABEL_68;
          }
        }
        if( v11 == v33 )
          goto LABEL_42;
        v64 = 0;
        v24 = !_BitScanReverse64((unsigned __int64 *)&v46, v12);
        if( v24 )
          v32 = 64;
        else
          v32 = 63 - v46;
        ++v11;
        v64 = v32;
        v12 = *v11;
      }
      v38 = -(__int64)v32;
LABEL_68:
      v15 = (((__int64)v11 - v6) >> 3 << 6) + v38;
LABEL_10:
      if( v15 > v9 )
        goto LABEL_42;
      goto LABEL_11;
    }
    while( 1 )
    {
      while( v12 < 0 )
      {
        if( (unsigned __int64)++v11 > v10 )
          goto LABEL_41;
        v12 = *v11;
      }
      v61 = 0;
      v24 = !_BitScanReverse64((unsigned __int64 *)&v29, v12);
      if( !v24 )
        v13 = 63 - v29;
      v61 = v13;
      v15 = (((((__int64)v11 - v6) >> 3) + 1) << 6) - v13;
      if( v15 > v9 )
        goto LABEL_41;
      v30 = v1 - v13;
      if( v1 == v13 )
        goto LABEL_11;
      v12 = *++v11;
      if( v30 >= 0x40 )
      {
        if( *v11 )
          goto LABEL_38;
        v30 -= 64i64;
        if( !v30 )
          goto LABEL_11;
        v12 = *++v11;
      }
      v24 = !_BitScanForward64(&v31, v12);
      if( v24 )
        v31 = 64i64;
      v62 = v31;
      if( v31 >= v30 )
        goto LABEL_11;
LABEL_38:
      v13 = 64;
    }
  }
  v16 = v7 & 0xFFFFFFFFFFFFFFF8ui64;
LABEL_13:
  if( v16 == -1i64 )
    return 0i64;
  CurrentThread = (_ETHREAD *)KeGetCurrentThread();
  --CurrentThread->Tcb.SpecialApcDisable;
  ExAcquirePushLockExclusiveEx((_EX_PUSH_LOCK *)KeGetCurrentThread()->ApcState.Process->Session + 103, 0i64);
  ClearBitsAndSet = RtlFindClearBitsAndSetEx(v4, v1, v16);
  if( ClearBitsAndSet == -1i64 )
  {
    v48 = (UINT64)KeGetCurrentThread()->ApcState.Process->Session + 824;
    if( (_InterlockedExchangeAdd64((volatile signed __int64 *)v48, 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
      ExfTryToWakePushLock((_EX_PUSH_LOCK *)v48);
    LODWORD(v66) = 0;
    v49 = (_ETHREAD *)KeGetCurrentThread();
    if( MiGetSystemRegionType(v48) == 1 )
      SessionId = MmGetSessionIdEx(v49->Tcb.ApcState.Process);
    else
      SessionId = -1;
    --v49->Tcb.SpecialApcDisable;
    v51 = ++v49->Tcb.AbAllocationRegionCount;
    v52 = ((char)v49->Tcb.AbEntrySummary | (char)v49->Tcb.AbOrphanedEntrySummary) ^ 0x3F;
    while( 1 )
    {
      v24 = !_BitScanReverse((unsigned int *)&v53, v52);
      if( v24 )
        goto LABEL_118;
      v54 = &v49->Tcb.LockEntries[v53];
      v52 &= ~(1 << v53);
      if( (v54->AcquiredByte & 1) != 0
        && (v54->LockState.$E8276A2CF8B819ED32D1B6FEB35D730A::_bf_0 & 1) == 0
        && (v54->LockState.$E8276A2CF8B819ED32D1B6FEB35D730A::_bf_0 & 0x7FFFFFFFFFFFFFFCi64) == (v48 & 0x7FFFFFFFFFFFFFFCi64)
        && v54->LockState.SessionId == SessionId )
      {
        v54->AcquiredByte &= ~1u;
        if( v54->LockState.$E8276A2CF8B819ED32D1B6FEB35D730A::_bf_0 )
          break;
      }
    }
    if( !v54 )
    {
LABEL_118:
      if( (*(&v49->Tcb.MiscFlags + 1) & 0x10000) == 0 )
        KeBugCheckEx(0x162u, v49, (PVOID)v48, (PVOID)SessionId, 0i64);
      goto LABEL_130;
    }
    v54->CrossThreadReleasableAndBusyByte |= 2u;
    if( v54->LockState.$E8276A2CF8B819ED32D1B6FEB35D730A::_bf_0 < 0 )
      KiAbEntryRemoveFromTree(v54);
    LODWORD(v66) = v54->BoostBitmap.AllFields & 0x1FFFF;
    v54->BoostBitmap.AllFields &= 0xFFFE0000;
    v54->ThreadLocalFlags &= ~1u;
    v54->LockState.$E8276A2CF8B819ED32D1B6FEB35D730A::_bf_0 = 0i64;
    v55 = v54 - v49->Tcb.LockEntries;
    if( v51 == 1 )
      v49->Tcb.AbEntrySummary |= 1 << v55;
    else
      _InterlockedOr8((volatile signed __int8 *)&v49->Tcb.AbOrphanedEntrySummary, 1 << v55);
LABEL_130:
    --v49->Tcb.AbAllocationRegionCount;
    KiAbThreadRemoveBoosts(&v49->Tcb, (VOID *)v48, &v66);
    v24 = v49->Tcb.SpecialApcDisable++ == -1;
    if( v24 && ($F25F8C4BA33AF922A5F1AF68CD89DDDF *)v49->Tcb.ApcState.ApcListHead[0].Flink != &v49->Tcb.152 )
      KiCheckForKernelApcDelivery();
    KiLeaveGuardedRegionUnsafe((__int64)CurrentThread);
    return 0i64;
  }
  if( (_DWORD)v1 == 1 )
    *((_QWORD *)Session + 106) = ClearBitsAndSet + 1;
  *((_DWORD *)Session + 218) += v1;
  v19 = (UINT64)KeGetCurrentThread()->ApcState.Process->Session + 824;
  if( (_InterlockedExchangeAdd64((volatile signed __int64 *)v19, 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
    ExfTryToWakePushLock((_EX_PUSH_LOCK *)v19);
  LODWORD(a3) = 0;
  v20 = (_ETHREAD *)KeGetCurrentThread();
  if( MiGetSystemRegionType(v19) == 1 )
    v21 = MmGetSessionIdEx(v20->Tcb.ApcState.Process);
  else
    v21 = -1;
  --v20->Tcb.SpecialApcDisable;
  v22 = ++v20->Tcb.AbAllocationRegionCount;
  v23 = ((char)v20->Tcb.AbEntrySummary | (char)v20->Tcb.AbOrphanedEntrySummary) ^ 0x3F;
  while( 1 )
  {
    v24 = !_BitScanReverse((unsigned int *)&v25, v23);
    v67 = v25;
    if( v24 )
      break;
    v26 = &v20->Tcb.LockEntries[v25];
    v23 &= ~(1 << v25);
    if( (v26->AcquiredByte & 1) != 0
      && (v26->LockState.$E8276A2CF8B819ED32D1B6FEB35D730A::_bf_0 & 1) == 0
      && (v26->LockState.$E8276A2CF8B819ED32D1B6FEB35D730A::_bf_0 & 0x7FFFFFFFFFFFFFFCi64) == (v19 & 0x7FFFFFFFFFFFFFFCi64)
      && v26->LockState.SessionId == v21 )
    {
      v26->AcquiredByte &= ~1u;
      if( v26->LockState.$E8276A2CF8B819ED32D1B6FEB35D730A::_bf_0 )
      {
        if( v26 )
        {
          v26->CrossThreadReleasableAndBusyByte |= 2u;
          if( v26->LockState.$E8276A2CF8B819ED32D1B6FEB35D730A::_bf_0 < 0 )
            KiAbEntryRemoveFromTree(v26);
          LODWORD(a3) = v26->BoostBitmap.AllFields & 0x1FFFF;
          v26->BoostBitmap.AllFields &= 0xFFFE0000;
          v26->ThreadLocalFlags &= ~1u;
          v26->LockState.$E8276A2CF8B819ED32D1B6FEB35D730A::_bf_0 = 0i64;
          v27 = v26 - v20->Tcb.LockEntries;
          if( v22 == 1 )
            v20->Tcb.AbEntrySummary |= 1 << v27;
          else
            _InterlockedOr8((volatile signed __int8 *)&v20->Tcb.AbOrphanedEntrySummary, 1 << v27);
          goto LABEL_33;
        }
        break;
      }
    }
  }
  if( (*(&v20->Tcb.MiscFlags + 1) & 0x10000) == 0 )
    KeBugCheckEx(0x162u, v20, (PVOID)v19, (PVOID)v21, 0i64);
LABEL_33:
  --v20->Tcb.AbAllocationRegionCount;
  KiAbThreadRemoveBoosts(&v20->Tcb, (VOID *)v19, &a3);
  v24 = v20->Tcb.SpecialApcDisable++ == -1;
  if( v24 && ($F25F8C4BA33AF922A5F1AF68CD89DDDF *)v20->Tcb.ApcState.ApcListHead[0].Flink != &v20->Tcb.152 )
    KiCheckForKernelApcDelivery();
  KiLeaveGuardedRegionUnsafe((__int64)CurrentThread);
  return(VOID *)(qword_140C4CAE0 + (ClearBitsAndSet << 21));
}

Referenced by:

MiExpandPtes
MiReservePoolMemory