ExFreeHeapPool

NTSTATUS __stdcall ExFreeHeapPool(PVOID BugCheckParameter2){
  char v2; 
  int v3; 
  __int64 v4; 
  unsigned __int64 v5; 
  _OWORD *v6; 
  UINT64 v7; 
  int v8; 
  unsigned int v9; 
  UINT64 v10; 
  int v11; 
  UINT8 *v12; 
  unsigned int v13; 
  __int64 v14; 
  int v15; 
  UINT8 *v16; 
  __int64 v17; 
  __int64 v18; 
  __int64 v19; 
  int v20; 
  unsigned int v21; 
  int v22; 
  INT64 v23; 
  INT64 v24; 
  char v25; 
  INT64 v26; 
  char v27; 
  char v28; 
  __int64 v29; 
  UINT64 v30; 
  INT64 v31; 
  _EPROCESS *v32; 
  UINT64 v33; 
  __int64 v34; 
  INT64 v35; 
  int v36; 
  UINT8 CurrentIrql; 
  int v38; 
  __int64 v39; 
  volatile signed __int32 *v40; 
  unsigned __int64 v41; 
  int v42; 
  unsigned int v43; 
  __int64 v44; 
  union _RTL_RUN_ONCE *v45; 
  INT64 v46; 
  union _RTL_RUN_ONCE *HeapManager; 
  INT64 v48; 
  int v49; 
  char v50; 
  int v51; 
  __int128 v53; 
  _DWORD v54[4]; 
  __int128 a2; 
  _DWORD a1[4]; 
  __int128 v57; 
  UINT64 v58; 
  int a4; 
  _OWORD **a3; 
  int v61; 
  int v62; 
  if( (unsigned __int64)BugCheckParameter2 >= 0xFFFF800000000000ui64
    && *((_BYTE *)&antNameB + (((unsigned __int64)BugCheckParameter2 >> 39) & 0x1FF) - 256) == 1 )
  {
    v2 = 5;
  }
  else
  {
    v2 = 3;
  }
  v53 = 0i64;
  *(_WORD *)((char *)&v53 + 1) = 1;
  LOBYTE(v53) = v2;
  v57 = v53;
  if( (_WORD)BugCheckParameter2 )
  {
    v3 = 0;
LABEL_6:
    v4 = v3;
    v61 = 0x100000;
    v62 = 0x1000000;
    v5 = (unsigned __int64)BugCheckParameter2 & ~((unsigned int)*(&v61 + v3) - 1i64);
    v6 = (_OWORD *)((RtlpHpHeapGlobals ^ v5 ^ *(_QWORD *)(v5 + 16) ^ 0xA2E64EADA2E64EADui64) - 192 * v4 - 256);
    goto LABEL_7;
  }
  *(_OWORD *)v54 = v53;
  HeapManager = RtlpHpEnvGetHeapManager(v54);
  v48 = RtlCSparseBitmapBitmaskRead(
          (INT64)&HeapManager[2],
          2 * (((unsigned __int64)BugCheckParameter2 - HeapManager[1].Value) >> 20));
  if( v48 )
  {
    v3 = v48 - 1;
    if( v3 != 2 )
      goto LABEL_6;
  }
  a3 = 0i64;
  a4 = 0;
  a2 = v53;
  RtlpHpQueryVA((__int64)BugCheckParameter2, &a2, &a3, &a4);
  v6 = *a3;
LABEL_7:
  if( !v6 )
    KeBugCheckEx(0xC2u, 0i64, 0i64, (ULONG_PTR)BugCheckParameter2, 0i64);
  if( ExpSpecialAllocations && (unsigned int)ExpHpIsSpecialPoolHeap((UINT64)v6) )
  {
    if( _InterlockedExchangeAdd(&ExpSpecialAllocations, 0xFFFFFFFF) == 1 )
      _InterlockedDecrement(&dword_140C4EC18);
    LODWORD(v30) = ExpFreeHeapSpecialPool(v6, (UINT64)BugCheckParameter2);
    return v30;
  }
  if( ((unsigned __int16)BugCheckParameter2 & 0xFFF) != 0 )
  {
    v7 = (UINT64)BugCheckParameter2 - 16;
    if( (*((char *)BugCheckParameter2 - 13) & 4) != 0 )
    {
      v7 -= 16i64 * (unsigned __int8)*(_WORD *)v7;
      *(_BYTE *)(v7 + 3) |= 4u;
    }
    v8 = *(unsigned __int8 *)(v7 + 3);
    v9 = *(_DWORD *)(v7 + 4);
    if( (v8 & 8) != 0 )
    {
      v32 = (_EPROCESS *)(v7 ^ ExpPoolQuotaCookie ^ *(_QWORD *)(v7 + 8));
      if( v32 )
      {
        if( (unsigned __int64)v32 < 0xFFFF800000000000ui64 || (*(_BYTE *)v32 & 0x7F) != 3 )
          KeBugCheckEx(
            0xC2u,
            0xDui64,
            v7 + 16,
            *(unsigned int *)(v7 + 4),
            v7 ^ ExpPoolQuotaCookie ^ *(_QWORD *)(v7 + 8));
        v33 = v9;
        if( v32 != (_EPROCESS *)PsInitialSystemProcess )
        {
          PspReturnQuota(
            *(CHAR **)((v7 ^ ExpPoolQuotaCookie ^ *(_QWORD *)(v7 + 8)) + 0x568),
            v7 ^ ExpPoolQuotaCookie ^ *(_QWORD *)(v7 + 8),
            v8 & 1,
            16i64 * (unsigned __int8)*(_WORD *)(v7 + 2));
          v33 = *(unsigned int *)(v7 + 4);
        }
        ObDereferenceObjectDeferDeleteWithTag(v32, v33);
      }
    }
    v10 = 16i64 * (unsigned __int8)*(_WORD *)(v7 + 2);
  }
  else
  {
    v36 = MiDeterminePoolType((UINT64)BugCheckParameter2);
    if( v36 == 32 )
      v36 = 0;
    CurrentIrql = KeGetCurrentIrql();
    __writecr8(2ui64);
    if( !ExpTryAcquireSpinLockShared((INT64 *)&ExpLargePoolTableLock) )
    {
      ExpWaitForSpinLockSharedAndAcquire((INT64 *)&ExpLargePoolTableLock, CurrentIrql);
      v38 = 1;
    }
    if( (v36 & 0x20) != 0 )
    {
      v39 = *(_QWORD *)(qword_140C4DB20 + 992);
      v40 = (volatile signed __int32 *)(qword_140C4DB20 + 864);
      v41 = *(_QWORD *)(qword_140C4DB20 + 1000);
    }
    else
    {
      v39 = PoolBigPageTable;
      v40 = &ExpPoolBigEntriesInUse;
      v41 = PoolBigPageTableSize;
    }
LABEL_74:
    v42 = v38;
    v43 = (((40543 * (unsigned __int64)(unsigned int)((unsigned __int64)BugCheckParameter2 >> 12)) >> 32) ^ (40543 * ((unsigned __int64)BugCheckParameter2 >> 12))) & (v41 - 1);
    while( *(PVOID *)(v39 + 24i64 * v43) != BugCheckParameter2 )
    {
      if( ++v43 >= v41 )
      {
        if( !v42 )
        {
LABEL_103:
          if( (v36 & 0x21) != 0
            || v39 != PoolBigPageTable
            || (unsigned int)MmGetSessionIdEx(*((_QWORD *)KeGetCurrentThread() + 23)) == -1
            || (v39 = *(_QWORD *)(qword_140C4DB20 + 992),
                v40 = (volatile signed __int32 *)(qword_140C4DB20 + 864),
                v41 = *(_QWORD *)(qword_140C4DB20 + 1000),
                !v39)
            || (v38 = 1, !v41) )
          {
            KeBugCheckEx(0x19u, 0x22ui64, (ULONG_PTR)BugCheckParameter2, v36, 0i64);
          }
          goto LABEL_74;
        }
        v43 = 0;
        v42 = 0;
      }
    }
    v44 = v39 + 24i64 * v43;
    if( !v44 )
      goto LABEL_103;
    v9 = *(_DWORD *)(v44 + 8);
    v10 = *(_QWORD *)(v44 + 16);
    v8 = (*(_DWORD *)(v44 + 12) >> 8) & 0xFFF;
    _InterlockedDecrement(v40);
    _InterlockedIncrement64((volatile signed __int64 *)v44);
    _InterlockedAnd(&ExpLargePoolTableLock, 0xBFFFFFFF);
    _InterlockedDecrement(&ExpLargePoolTableLock);
    __writecr8(CurrentIrql);
    v7 = (UINT64)BugCheckParameter2;
  }
  if( (ExpPoolFlags & 0x207) != 0 )
  {
    if( (ExpPoolFlags & 0x200) != 0 && !v8 )
      ExpCheckForLookaside((PVOID)v7, v10);
    if( (ExpPoolFlags & 1) != 0 )
      KeCheckForTimer((PVOID)v7, v10);
    if( (ExpPoolFlags & 4) != 0 )
      ExpCheckForResource((PVOID)v7, v10);
    if( (ExpPoolFlags & 2) != 0 )
      ExpCheckForWorker((PVOID)v7, v10);
  }
  if( (ExpPoolFlags & 0x10) != 0 )
    VfFreePoolNotification((PVOID)v7, v10);
  if( v9 == PoolHitTag )
    __debugbreak();
  if( (v8 & 0x20) != 0 )
  {
    v12 = (UINT8 *)ExpSessionPoolTrackTable;
    v11 = ExpSessionPoolTrackTableMask;
  }
  else
  {
    v11 = PoolTrackTableMask;
    v12 = (&ExPoolTagTables)[*((unsigned int *)KeGetPcr() + 105)];
  }
  v13 = v11 & ((40543 * v9) ^ ((40543 * (unsigned __int64)v9) >> 32));
  while( 1 )
  {
    v14 = 56i64 * v13;
    v15 = *(_DWORD *)&v12[v14];
    v16 = &v12[v14];
    if( v15 == v9 )
      break;
    if( v15 || (v8 & 0x20) != 0 || (v49 = *(_DWORD *)((char *)PoolTrackTable + v14)) == 0 )
    {
      v13 = v11 & (v13 + 1);
      if( v13 == (v11 & ((40543 * v9) ^ ((40543 * (unsigned __int64)v9) >> 32))) )
      {
        ExpRemovePoolTrackerExpansion(v9, v10, (POOL_TYPE)v8);
        goto LABEL_26;
      }
    }
    else
    {
      *(_DWORD *)v16 = v49;
    }
  }
  if( (v8 & 1) != 0 )
  {
    v17 = 32i64;
    v18 = 48i64;
  }
  else
  {
    v17 = 8i64;
    v18 = 24i64;
  }
  _InterlockedIncrement64((volatile signed __int64 *)&v16[v18]);
  _InterlockedExchangeAdd64((volatile signed __int64 *)&v16[v17], -(__int64)v10);
LABEL_26:
  if( (v8 & 0x40) != 0 )
    VerifierFreeTrackedPool(BugCheckParameter2, v10, (unsigned int)v8, 0i64);
  v19 = *((_QWORD *)v6 + 5);
  if( v10 - 513 <= 0xD7F && v19 )
  {
    v34 = v19
        + (((unsigned int)*((unsigned __int8 *)RtlpLfhBucketIndexMap + ((unsigned __int64)(unsigned int)(v10 + 15) >> 4))
          - 33
          + 1i64) << 6);
    ++*(_DWORD *)(v34 + 28);
    if( *(_WORD *)v34 < *(_WORD *)(v34 + 16) )
    {
      LODWORD(v30) = (unsigned int)RtlpInterlockedPushEntrySList((PSLIST_HEADER)v34, (PSLIST_ENTRY)v7);
      return v30;
    }
    ++*(_DWORD *)(v34 + 32);
  }
  v20 = *((_DWORD *)v6 + 55);
  v21 = *((_DWORD *)v6 + 5) & 0x11000001;
  if( v20 && v20 == *((_DWORD *)KeGetCurrentThread() + 288) )
    v21 = *((_DWORD *)v6 + 5) & 0x11000000 | 1;
  if( (v21 & 0x1000000) != 0
    || !*((_DWORD *)v6 + 6)
    || (v30 = RtlpHpExtrasGet(v6, v7, v21, 0i64), v30 - 1 > 0xFFFFFFFFFFFFFFFDui64)
    || (v50 = *(_BYTE *)(v30 + 2), (v50 & 0xF) == 0)
    || (v51 = v50 & 0xF) != 0
    && (_WORD)v51 == 1
    && (LODWORD(v30) = ((__int64(__fastcall *)(_OWORD *, UINT64, __int64, UINT64))RtlpInterceptorRoutines)(
                         v6,
                         v7,
                         3i64,
                         v30 + 16),
        (v30 & 0x80000000) == 0i64) )
  {
    if( (*((_DWORD *)v6 + 5) & 0x10000000) != 0 && RtlpHpSizeHeap((INT64)v6, v7, v21) == -1 )
    {
      v31 = (INT64)v6;
      goto LABEL_48;
    }
    if( (_WORD)v7 )
    {
      v22 = 0;
    }
    else
    {
      *(_OWORD *)a1 = *v6;
      v45 = RtlpHpEnvGetHeapManager(a1);
      v46 = RtlCSparseBitmapBitmaskRead((INT64)&v45[2], 2 * ((v7 - v45[1].Value) >> 20));
      if( !v46 || (v22 = v46 - 1, v22 == 2) )
      {
        LODWORD(v30) = RtlpHpLargeFree(v6, (PVOID)v7, v21);
        return v30;
      }
    }
    LODWORD(v58) = 0;
    v23 = (INT64)&v6[12 * v22 + 16];
    v24 = v7 & *(_QWORD *)v23;
    if( ((unsigned __int64)RtlpHpHeapGlobals ^ v23 ^ v24 ^ *(_QWORD *)(v24 + 0x10)) == 0xA2E64EADA2E64EADui64 )
    {
      v25 = *(_BYTE *)(v23 + 8);
      v26 = v24 + 32 * ((unsigned __int64)(unsigned int)(v7 - v24) >> v25);
      if( v26 )
      {
        v27 = *(_BYTE *)(v26 + 24);
        if( (v27 & 1) != 0 )
        {
          if( (v27 & 2) != 0 )
          {
            if( (v27 & 0xCu) >= 8 || (((1 << v25) - 1) & v7) == 0 )
            {
LABEL_43:
              if( v7 <= ((unsigned __int64)v26 & *(_QWORD *)v23) + ((v26 - (v26 & *(_QWORD *)v23)) >> 5 << v25) )
              {
                LOBYTE(v30) = RtlpHpSegPageRangeShrink(v23, v26, v24, v21);
              }
              else
              {
                v28 = *(_BYTE *)(v26 + 24) & 0xC;
                v29 = (v26 & *(_QWORD *)v23) + ((v26 - (v26 & *(_QWORD *)v23)) >> 5 << v25);
                if( v28 == 8 )
                {
                  LODWORD(v30) = RtlpHpLfhSubsegmentFreeBlock(*(_QWORD *)(v23 + 24), v29, v7, v21);
                }
                else
                {
                  LODWORD(v30) = RtlpHpVsContextFree(*(_QWORD *)(v23 + 32), v29, v7, v21, &v58);
                  if( (_DWORD)v30 )
                  {
                    v35 = *(_QWORD *)(v23 + 24);
                    LODWORD(v30) = *(unsigned __int16 *)(v35 + 60) - 16;
                    if( (unsigned int)v58 <= (unsigned int)v30 )
                      LODWORD(v30) = RtlpHpLfhBucketUpdateStats(v35, (unsigned int)v58, 0i64);
                  }
                }
              }
              return v30;
            }
          }
          else
          {
            v26 -= 32i64 * *(unsigned __int8 *)(v26 + 31);
            v24 = *(unsigned __int8 *)(v26 + 24);
            if( (v24 & 3) == 3 )
            {
              LOBYTE(v24) = v24 & 0xC;
              if( (unsigned __int8)v24 >= 8u )
                goto LABEL_43;
            }
          }
        }
      }
    }
    v31 = *(_QWORD *)(v23 + 56);
LABEL_48:
    RtlpLogHeapFailure(9i64, v31, v7, 0i64, 0i64, 0i64);
  }
  return v30;
}

Referenced by:

AdtpBuildAccessReasonAuditString
AdtpBuildAccessReasonAuditStringInternal
AdtpBuildStagingReasonAuditStringInternal
AdtpCleanupParameterAllocations
AdtpPackageParameters
ApiSetComposeSchema
ApiSetReleaseSchema
BgpFwAllocateMemory
BiLogFileOwnerProcess
BiMapEfiDeviceForSpaces
BiSpacesUpdatePhysicalDevicePath
BiWasFirmwareModified
CcInitializeCacheManager
ExDeleteResourceLite
ExFreeAutoExpandPushLock
ExFreeCacheAwarePushLock
ExFreeCacheAwareRundownProtection
ExFreePoolEx
ExFreePoolWithTag
ExGetSessionPoolTagInfo
ExGetWakeTimerList
ExpAllocateAsid
ExpFinalizeTimerDeletion
ExpPrepareNewSvmDevice
ExpResourceTimeoutCaptureLiveDump
ExpSaBinaryArrayRemove
ExpSaPageGroupDescriptorAllocate
ExpSaPageGroupDescriptorFree
ExpWorkerFactoryCompletionPacketRoutine
NtWaitForWorkViaWorkerFactory
OpenGlobalizationUserSettingsKey_ForMua
OpenGlobalizationUserSettingsKey_ForSingleUserModel
RtlpMuiRegAddAlternateCodePage
RtlpMuiRegCreateKernelRegistryInfo
RtlpMuiRegLoadLicInformation
SafeReallocBlob
SbpAddTransportToInstance
SbpStartLanman
VhdiInitializeBootDisk
VhdiMountVhdFile
VhdiQueryVolumeVhdFilePath
WheaPersistBadPageToBcd
WheapFreeDriverPacketBuffer
WheapFreeErrorRecord
WheapInitializeErrorSourceTable
sub_1405BD220
sub_1405BD7FC