RtlpFreeHeap

INT64 __fastcall RtlpFreeHeap(
        _HEAP *Heap,
        UINT64 Flags,
        _HEAP_ENTRY *BusyBlock,
        VOID *BaseAddress,
        UINT64 *a5,
        VOID *a6){
  char v8; 
  int v10; 
  int v11; 
  void **BlocksIndex; 
  unsigned __int8 v13; 
  _HEAP_FREE_ENTRY *v14; 
  CHAR v15; 
  unsigned __int16 v16; 
  bool v17; 
  unsigned __int64 v18; 
  _LIST_ENTRY *p_FreeLists; 
  __int64 *Entry; 
  unsigned int v21; 
  unsigned __int16 v22; 
  _QWORD *p_Flink; 
  INT64 *v24; 
  unsigned int *v25; 
  unsigned __int64 Size; 
  unsigned __int64 v27; 
  int v28; 
  _HEAP_FREE_ENTRY *v29; 
  unsigned __int64 v30; 
  _LIST_ENTRY *v31; 
  __int64 *Flink; 
  unsigned int v33; 
  unsigned __int16 v34; 
  INT64 *v35; 
  _HEAP_ENTRY *v36; 
  void *PreviousBlockPrivateData; 
  _QWORD *v38; 
  INT64 *CompactHeader; 
  INT64 v40; 
  INT64 v41; 
  UINT64 *v42; 
  INT64 v43; 
  VOID *v44; 
  char v45; 
  PVOID BaseAddressa; 
  _HEAP_FREE_ENTRY *v47; 
  unsigned int v48; 
  unsigned int v49; 
  _HEAP_FREE_ENTRY *v50; 
  ULONG_PTR RegionSize; 
  RegionSize = 0i64;
  v8 = 0;
  v45 = 0;
  BaseAddressa = 0i64;
  if( Heap == (_HEAP *)BusyBlock )
  {
    RtlpLogHeapFailure(9i64, (INT64)Heap, (UINT64)BusyBlock, 0i64, 0i64, 0i64);
    return 0i64;
  }
  v10 = Heap->ForceFlags | Flags;
  v11 = v10 & 0x3C010F60;
  if( (v10 & 1) != 0 )
  {
    if( Heap->EncodeFlagMask )
    {
      BusyBlock->UnpackedEntry.SubSegmentCode ^= Heap->Encoding.UnpackedEntry.SubSegmentCode;
      if( BusyBlock->UnpackedEntry.SmallTagIndex != (LOBYTE(BusyBlock->Code1) ^ (unsigned __int8)(BYTE1(BusyBlock->AgregateCode) ^ BusyBlock->UnpackedEntry.Flags)) )
        RtlpAnalyzeHeapFailure((INT64)Heap, (UINT64)BusyBlock);
    }
  }
  else
  {
    ExAcquireResourceExclusiveLite((ERESOURCE *)Heap->LockVariable, 1u);
    v8 = 1;
    v45 = 1;
    if( Heap->EncodeFlagMask )
    {
      BusyBlock->UnpackedEntry.SubSegmentCode ^= Heap->Encoding.UnpackedEntry.SubSegmentCode;
      if( BusyBlock->UnpackedEntry.SmallTagIndex != (LOBYTE(BusyBlock->Code1) ^ (unsigned __int8)(BYTE1(BusyBlock->AgregateCode) ^ BusyBlock->UnpackedEntry.Flags)) )
        RtlpAnalyzeHeapFailure((INT64)Heap, (UINT64)BusyBlock);
    }
    BlocksIndex = (void **)Heap->BlocksIndex;
    do
    {
      if( BusyBlock->UnpackedEntry.Size < (unsigned __int64)*((unsigned int *)BlocksIndex + 2) )
        break;
      BlocksIndex = (void **)*BlocksIndex;
    }
    while( BlocksIndex );
  }
  v13 = BusyBlock->UnpackedEntry.Flags;
  if( (v13 & 8) != 0 )
    BusyBlock->UnpackedEntry.Flags = v13 & 0xF7;
  if( BusyBlock->UnpackedEntry.UnusedBytes == 4 )
  {
    v36 = BusyBlock - 3;
    PreviousBlockPrivateData = BusyBlock[-1].UnpackedEntry.PreviousBlockPrivateData;
    BaseAddressa = (PVOID)((unsigned __int64)&BusyBlock[-3] & 0xFFFFFFFFFFFF0000ui64);
    Heap->Counters.TotalSizeInVirtualBlocks -= (unsigned __int64)PreviousBlockPrivateData;
    v38 = BusyBlock[-3].UnpackedEntry.PreviousBlockPrivateData;
    CompactHeader = (INT64 *)BusyBlock[-3].UnpackedEntry.CompactHeader;
    v40 = *CompactHeader;
    v41 = v38[1];
    if( *CompactHeader == v41 && (_HEAP_ENTRY *)v40 == v36 )
    {
      *CompactHeader = (INT64)v38;
      v38[1] = CompactHeader;
    }
    else
    {
      RtlpLogHeapFailure(13i64, 0i64, (UINT64)v36, v41, v40, 0i64);
    }
    if( v8 )
    {
      ExReleaseResourceLite((PERESOURCE)Heap->LockVariable);
      v8 = 0;
    }
    RegionSize = 0i64;
    ZwFreeVirtualMemory((PVOID)0xFFFFFFFFFFFFFFFFi64, &BaseAddressa, &RegionSize, 0x8000ui64);
    goto LABEL_84;
  }
  RegionSize = BusyBlock->UnpackedEntry.Size;
  v14 = RtlpCoalesceFreeBlocks(Heap, (_HEAP_FREE_ENTRY *)BusyBlock, &RegionSize, (UINT64 *)BaseAddress, v42, v44);
  v50 = v14;
  v16 = RegionSize;
  if( RegionSize < Heap->DeCommitFreeBlockThreshold
    || RegionSize + Heap->TotalFreeSize < Heap->DeCommitTotalFreeThreshold )
  {
    if( RegionSize > 0xFF00 )
    {
      RtlpInsertFreeBlock((INT64)Heap, (UINT64)v14, RegionSize);
      goto LABEL_84;
    }
    v17 = v11 == 0;
    v18 = (unsigned __int16)RegionSize;
    if( v17 )
    {
      v14->HeapEntry.UnpackedEntry.Flags = 0;
      v14->HeapEntry.UnpackedEntry.UnusedBytes = 0;
      p_FreeLists = &Heap->FreeLists;
      if( Heap->BlocksIndex )
        Entry = RtlpFindEntry((__int64)Heap, v16);
      else
        Entry = (__int64 *)p_FreeLists->Flink;
      while( p_FreeLists != (_LIST_ENTRY *)Entry )
      {
        if( Heap->EncodeFlagMask )
        {
          v21 = *((_DWORD *)Entry - 2);
          v48 = v21;
          if( (v21 & Heap->EncodeFlagMask) != 0 )
            v48 = v21 ^ Heap->Encoding.UnpackedEntry.SubSegmentCode;
          v22 = v48;
          v14 = v50;
          v8 = v45;
        }
        else
        {
          v22 = *((_WORD *)Entry - 4);
        }
        if( v18 <= v22 )
          break;
        Entry = (__int64 *)*Entry;
      }
      p_Flink = &v14->FreeList.Flink;
      v24 = (INT64 *)Entry[1];
      if( (__int64 *)*v24 == Entry )
      {
        *p_Flink = Entry;
        v14->FreeList.Blink = (_LIST_ENTRY *)v24;
        *v24 = (INT64)p_Flink;
        Entry[1] = (__int64)p_Flink;
      }
      else
      {
        RtlpLogHeapFailure(13i64, 0i64, (UINT64)Entry, 0i64, *v24, 0i64);
      }
      Heap->TotalFreeSize += v14->HeapEntry.UnpackedEntry.Size;
      v25 = (unsigned int *)Heap->BlocksIndex;
      if( !v25 )
        goto LABEL_72;
      Size = v14->HeapEntry.UnpackedEntry.Size;
      while( 1 )
      {
        v27 = v25[2];
        if( Size < v27 )
        {
          v28 = v14->HeapEntry.UnpackedEntry.Size;
          goto LABEL_71;
        }
        if( !*(_QWORD *)v25 )
          break;
        v25 = *(unsigned int **)v25;
      }
      v28 = v27 - 1;
LABEL_71:
      LODWORD(v43) = v28;
      RtlpHeapAddListEntry((INT64)Heap, (INT64)v25, v27, (INT64)p_Flink, v43, Size);
LABEL_72:
      if( Heap->EncodeFlagMask )
      {
        v14->HeapEntry.UnpackedEntry.SmallTagIndex = LOBYTE(v14->InterceptorValue) ^ BYTE1(v14->Code1) ^ v14->HeapEntry.UnpackedEntry.Flags;
        v14->HeapEntry.UnpackedEntry.SubSegmentCode ^= Heap->Encoding.UnpackedEntry.SubSegmentCode;
      }
      goto LABEL_84;
    }
    v14->HeapEntry.UnpackedEntry.Flags &= 0xF0u;
    v14->HeapEntry.UnpackedEntry.UnusedBytes = 0;
    if( (Heap->Flags & 0x40) == 0 )
    {
LABEL_51:
      v31 = &Heap->FreeLists;
      if( Heap->BlocksIndex )
        Flink = RtlpFindEntry((__int64)Heap, v18);
      else
        Flink = (__int64 *)v31->Flink;
      while( v31 != (_LIST_ENTRY *)Flink )
      {
        if( Heap->EncodeFlagMask )
        {
          v33 = *((_DWORD *)Flink - 2);
          v49 = v33;
          if( (v33 & Heap->EncodeFlagMask) != 0 )
            v49 = v33 ^ Heap->Encoding.UnpackedEntry.SubSegmentCode;
          v34 = v49;
          v14 = v50;
          v8 = v45;
        }
        else
        {
          v34 = *((_WORD *)Flink - 4);
        }
        if( v18 <= v34 )
          break;
        Flink = (__int64 *)*Flink;
      }
      p_Flink = &v14->FreeList.Flink;
      v35 = (INT64 *)Flink[1];
      if( (__int64 *)*v35 == Flink )
      {
        *p_Flink = Flink;
        v14->FreeList.Blink = (_LIST_ENTRY *)v35;
        *v35 = (INT64)p_Flink;
        Flink[1] = (__int64)p_Flink;
      }
      else
      {
        RtlpLogHeapFailure(13i64, 0i64, (UINT64)Flink, 0i64, *v35, 0i64);
      }
      Heap->TotalFreeSize += v14->HeapEntry.UnpackedEntry.Size;
      v25 = (unsigned int *)Heap->BlocksIndex;
      if( !v25 )
        goto LABEL_72;
      Size = v14->HeapEntry.UnpackedEntry.Size;
      while( 1 )
      {
        v27 = v25[2];
        if( Size < v27 )
        {
          v28 = v14->HeapEntry.UnpackedEntry.Size;
          goto LABEL_71;
        }
        if( !*(_QWORD *)v25 )
          break;
        v25 = *(unsigned int **)v25;
      }
      v28 = v27 - 1;
      goto LABEL_71;
    }
    v29 = v14 + 1;
    v47 = v14 + 1;
    v30 = (16 * v18 - 32) >> 2;
    if( v30 )
    {
      if( ((unsigned __int8)v29 & 4) == 0 )
        goto LABEL_48;
      LODWORD(v29->HeapEntry.UnpackedEntry.PreviousBlockPrivateData) = -17891602;
      if( --v30 )
      {
        v29 = (_HEAP_FREE_ENTRY *)((char *)v14 + 36);
        v47 = (_HEAP_FREE_ENTRY *)((char *)v14 + 36);
LABEL_48:
        memset64(v29, 0xFEEEFEEEFEEEFEEEui64, v30 >> 1);
        if( (v30 & 1) != 0 )
          *((_DWORD *)&v29->HeapEntry.UnpackedEntry + v30 - 1) = -17891602;
      }
    }
    v14->HeapEntry.UnpackedEntry.Flags |= 4u;
    goto LABEL_51;
  }
  RtlpDeCommitFreeBlock((INT64)Heap, (UINT64)v14, RegionSize, v15);
LABEL_84:
  if( v8 )
    ExReleaseResourceLite((PERESOURCE)Heap->LockVariable);
  return 1i64;
}

Referenced by:

RtlpFreeHeapInternal