RtlpCreateSplitBlock
UINT8 __stdcall RtlpCreateSplitBlock(
_HEAP *Heap,
_HEAP_SEGMENT *Segment,
_HEAP_FREE_ENTRY *SplitBlock,
UINT8 FreeFlags,
UINT8 PatternCheck,
UINT16 PreviousBlockSize,
UINT64 FreeSize){
int v7;
_HEAP *v10;
unsigned __int64 v11;
__int16 v13;
char *v14;
VOID **v15;
_QWORD *v16;
char *v17;
VOID *v18;
_HEAP_LIST_LOOKUP *BlocksIndex;
_LIST_ENTRY *v20;
unsigned __int64 i;
_HEAP_LIST_LOOKUP *ExtendedLookup;
int v23;
char v24;
unsigned __int64 v25;
__int64 v26;
UINT64 v27;
_LIST_ENTRY *v28;
_LIST_ENTRY *Flink;
unsigned int v30;
int v31;
unsigned __int16 v32;
_LIST_ENTRY *v33;
_LIST_ENTRY *p_FreeList;
_HEAP_LIST_LOOKUP *v35;
_LIST_ENTRY *Size;
unsigned __int64 k;
_HEAP_LIST_LOOKUP *v38;
_LIST_ENTRY *v39;
_HEAP_FREE_ENTRY *v40;
unsigned __int64 v41;
_LIST_ENTRY *p_FreeLists;
_LIST_ENTRY *Entry;
unsigned int EncodeFlagMask;
int Blink;
unsigned __int16 v46;
_LIST_ENTRY *v47;
unsigned __int64 j;
_HEAP_LIST_LOOKUP *v49;
_LIST_ENTRY *v51;
_LIST_ENTRY *v52;
unsigned int v53;
int v54;
unsigned __int16 v55;
_LIST_ENTRY *v56;
unsigned __int64 m;
_HEAP_LIST_LOOKUP *v58;
_HEAP_FREE_ENTRY *v59;
unsigned __int64 v60;
_LIST_ENTRY *v61;
_LIST_ENTRY *v62;
unsigned int v63;
int v64;
unsigned __int16 v65;
_LIST_ENTRY *v66;
_LIST_ENTRY *v67;
_HEAP_LIST_LOOKUP *v68;
unsigned __int64 n;
_HEAP_LIST_LOOKUP *v70;
_LIST_ENTRY *v71;
VOID *Param2;
unsigned int v73;
unsigned int v74;
unsigned int v75;
unsigned int v76;
UINT64 FreeSizea;
v7 = 0;
SplitBlock->HeapEntry.UnpackedEntry.UnusedBytes = 0;
SplitBlock->HeapEntry.UnpackedEntry.Flags = FreeFlags;
SplitBlock->HeapEntry.UnpackedEntry.PreviousSize = Heap->Encoding.UnpackedEntry.PreviousSize ^ PreviousBlockSize;
v10 = Segment->Heap;
if( v10 == (_HEAP *)Segment )
{
LOBYTE(v11) = 0;
}
else
{
v11 = ((unsigned __int64)((char *)SplitBlock - (char *)Segment) >> 16) + 1;
if( v11 >= 0xFE )
RtlpLogHeapFailure(heap_failure_entry_corruption, v10, SplitBlock, Segment, 0i64);
}
SplitBlock->HeapEntry.UnpackedEntry.SegmentOffset = v11;
v13 = FreeSize;
v14 = &SplitBlock->HeapEntry.gap0[16 * FreeSize];
SplitBlock->HeapEntry.UnpackedEntry.SmallTagIndex = 0;
SplitBlock->HeapEntry.UnpackedEntry.Size = FreeSize;
while( (((unsigned __int8)v14[10] ^ Heap->Encoding.UnpackedEntry.Flags & (Heap->EncodeFlagMask >> 20)) & 1) == 0 )
{
if( Heap->EncodeFlagMask )
{
*((_DWORD *)v14 + 2) ^= Heap->Encoding.UnpackedEntry.SubSegmentCode;
if( v14[11] != ((unsigned __int8)v14[8] ^ (unsigned __int8)(v14[9] ^ v14[10])) )
RtlpAnalyzeHeapFailure(Heap, &SplitBlock->HeapEntry + FreeSize);
}
v15 = (VOID **)*((_QWORD *)v14 + 3);
v16 = (_QWORD *)*((_QWORD *)v14 + 2);
FreeSizea = (UINT64)v15;
v17 = (char *)*v15;
v18 = (VOID *)v16[1];
if( *v15 == v18 && v17 == v14 + 16 )
{
Heap->TotalFreeSize -= *((unsigned __int16 *)v14 + 4);
BlocksIndex = (_HEAP_LIST_LOOKUP *)Heap->BlocksIndex;
if( BlocksIndex )
{
v20 = (_LIST_ENTRY *)*((unsigned __int16 *)v14 + 4);
for( i = BlocksIndex->ArraySize; ; i = ExtendedLookup->ArraySize )
{
if( (unsigned __int64)v20 < i )
{
v23 = *((unsigned __int16 *)v14 + 4);
goto LABEL_20;
}
ExtendedLookup = BlocksIndex->ExtendedLookup;
if( !BlocksIndex->ExtendedLookup )
break;
BlocksIndex = BlocksIndex->ExtendedLookup;
}
v23 = BlocksIndex->ArraySize - 1;
LABEL_20:
LODWORD(Param2) = v23;
RtlpHeapRemoveListEntry(Heap, BlocksIndex, v20, (UINT64)(v14 + 16), (UINT64)Param2);
v15 = (VOID **)FreeSizea;
}
*v15 = v16;
v16[1] = v15;
if( PatternCheck )
{
v24 = v14[10];
if( (v24 & 4) != 0 )
{
v25 = 16i64 * *((unsigned __int16 *)v14 + 4) - 32;
if( (v24 & 2) != 0 && v25 > 4 )
v25 = 16i64 * *((unsigned __int16 *)v14 + 4) - 36;
LODWORD(v26) = RtlCompareMemoryUlong(v14 + 32, v25, 0xFEEEFEEEui64);
if( v26 != v25 )
{
DbgPrint(
"HEAP: Free Heap block %p modified at %p after it was freed\n",
&SplitBlock->HeapEntry.UnpackedEntry + FreeSize,
&v14[v26 + 32]);
if( (_BYTE)KdDebuggerEnabled )
__debugbreak();
}
}
}
SplitBlock->HeapEntry.UnpackedEntry.Flags = v14[10];
v27 = *((unsigned __int16 *)v14 + 4) + FreeSize;
if( v27 > 0xFF00 )
{
RtlpInsertFreeBlock(Heap, SplitBlock, v27);
return 1;
}
SplitBlock->HeapEntry.UnpackedEntry.Size = v27;
*(&SplitBlock->HeapEntry.UnpackedEntry.PreviousSize + 8 * v27) = Heap->Encoding.UnpackedEntry.PreviousSize ^ v27;
SplitBlock->HeapEntry.UnpackedEntry.UnusedBytes = 0;
if( PatternCheck )
{
SplitBlock->HeapEntry.UnpackedEntry.Flags &= 0xF0u;
if( (Heap->Flags & 0x40) != 0 )
{
v40 = SplitBlock + 1;
v41 = (16 * (unsigned __int64)(unsigned __int16)v27 - 32) >> 2;
if( v41 )
{
if( ((unsigned __int8)v40 & 4) != 0 )
{
--v41;
LODWORD(v40->HeapEntry.UnpackedEntry.PreviousBlockPrivateData) = -17891602;
v40 = (_HEAP_FREE_ENTRY *)((char *)SplitBlock + 36);
}
memset64(v40, 0xFEEEFEEEFEEEFEEEui64, v41 >> 1);
if( (v41 & 1) != 0 )
*((_DWORD *)&v40->HeapEntry.UnpackedEntry + v41 - 1) = -17891602;
}
SplitBlock->HeapEntry.UnpackedEntry.Flags |= 4u;
}
p_FreeLists = &Heap->FreeLists;
if( Heap->BlocksIndex )
Entry = RtlpFindEntry(Heap, (unsigned __int16)v27);
else
Entry = p_FreeLists->Flink;
if( p_FreeLists != Entry )
{
EncodeFlagMask = Heap->EncodeFlagMask;
do
{
if( EncodeFlagMask )
{
Blink = (int)Entry[-1].Blink;
EncodeFlagMask = Heap->EncodeFlagMask;
LOWORD(v74) = Blink;
if( (Blink & EncodeFlagMask) != 0 )
v74 = Heap->Encoding.UnpackedEntry.SubSegmentCode ^ Blink;
v46 = v74;
}
else
{
v46 = (unsigned __int16)Entry[-1].Blink;
}
if( (unsigned __int16)v27 <= (unsigned __int64)v46 )
break;
Entry = Entry->Flink;
}
while( p_FreeLists != Entry );
}
v47 = Entry->Blink;
p_FreeList = &SplitBlock->FreeList;
if( v47->Flink == Entry )
{
p_FreeList->Flink = Entry;
SplitBlock->FreeList.Blink = v47;
v47->Flink = p_FreeList;
Entry->Blink = p_FreeList;
}
else
{
RtlpLogHeapFailure(heap_failure_freelists_corruption, 0i64, Entry, 0i64, v47->Flink);
}
Heap->TotalFreeSize += SplitBlock->HeapEntry.UnpackedEntry.Size;
v35 = (_HEAP_LIST_LOOKUP *)Heap->BlocksIndex;
if( v35 )
{
Size = (_LIST_ENTRY *)SplitBlock->HeapEntry.UnpackedEntry.Size;
for( j = v35->ArraySize; (unsigned __int64)Size >= j; j = v49->ArraySize )
{
v49 = v35->ExtendedLookup;
if( !v35->ExtendedLookup )
goto LABEL_84;
v35 = v35->ExtendedLookup;
}
goto LABEL_52;
}
}
else
{
SplitBlock->HeapEntry.UnpackedEntry.Flags = 0;
v28 = &Heap->FreeLists;
if( Heap->BlocksIndex )
Flink = RtlpFindEntry(Heap, (unsigned __int16)v27);
else
Flink = v28->Flink;
if( v28 != Flink )
{
v30 = Heap->EncodeFlagMask;
do
{
if( v30 )
{
v31 = (int)Flink[-1].Blink;
v30 = Heap->EncodeFlagMask;
LOWORD(v73) = v31;
if( (v31 & v30) != 0 )
v73 = Heap->Encoding.UnpackedEntry.SubSegmentCode ^ v31;
v32 = v73;
}
else
{
v32 = (unsigned __int16)Flink[-1].Blink;
}
if( (unsigned __int16)v27 <= (unsigned __int64)v32 )
break;
Flink = Flink->Flink;
}
while( v28 != Flink );
}
v33 = Flink->Blink;
p_FreeList = &SplitBlock->FreeList;
if( v33->Flink == Flink )
{
p_FreeList->Flink = Flink;
SplitBlock->FreeList.Blink = v33;
v33->Flink = p_FreeList;
Flink->Blink = p_FreeList;
}
else
{
RtlpLogHeapFailure(heap_failure_freelists_corruption, 0i64, Flink, 0i64, v33->Flink);
}
Heap->TotalFreeSize += SplitBlock->HeapEntry.UnpackedEntry.Size;
v35 = (_HEAP_LIST_LOOKUP *)Heap->BlocksIndex;
if( v35 )
{
Size = (_LIST_ENTRY *)SplitBlock->HeapEntry.UnpackedEntry.Size;
for( k = v35->ArraySize; (unsigned __int64)Size >= k; k = v38->ArraySize )
{
v38 = v35->ExtendedLookup;
if( !v35->ExtendedLookup )
goto LABEL_84;
v35 = v35->ExtendedLookup;
}
goto LABEL_52;
}
}
goto LABEL_54;
}
RtlpLogHeapFailure(heap_failure_freelists_corruption, Heap, v14 + 16, v18, v17);
if( v7 )
return 0;
v7 = 1;
}
*((_WORD *)v14 + 6) = Heap->Encoding.UnpackedEntry.PreviousSize ^ v13;
SplitBlock->HeapEntry.UnpackedEntry.UnusedBytes = 0;
if( !PatternCheck )
{
SplitBlock->HeapEntry.UnpackedEntry.Flags = 0;
v51 = &Heap->FreeLists;
if( Heap->BlocksIndex )
v52 = RtlpFindEntry(Heap, (unsigned __int16)FreeSize);
else
v52 = v51->Flink;
if( v51 != v52 )
{
v53 = Heap->EncodeFlagMask;
do
{
if( v53 )
{
v54 = (int)v52[-1].Blink;
v53 = Heap->EncodeFlagMask;
LOWORD(v75) = v54;
if( (v53 & v54) != 0 )
v75 = Heap->Encoding.UnpackedEntry.SubSegmentCode ^ v54;
v55 = v75;
}
else
{
v55 = (unsigned __int16)v52[-1].Blink;
}
if( (unsigned __int16)FreeSize <= (unsigned __int64)v55 )
break;
v52 = v52->Flink;
}
while( v51 != v52 );
}
v56 = v52->Blink;
p_FreeList = &SplitBlock->FreeList;
if( v56->Flink == v52 )
{
p_FreeList->Flink = v52;
SplitBlock->FreeList.Blink = v56;
v56->Flink = p_FreeList;
v52->Blink = p_FreeList;
}
else
{
RtlpLogHeapFailure(heap_failure_freelists_corruption, 0i64, v52, 0i64, v56->Flink);
}
Heap->TotalFreeSize += SplitBlock->HeapEntry.UnpackedEntry.Size;
v35 = (_HEAP_LIST_LOOKUP *)Heap->BlocksIndex;
if( v35 )
{
Size = (_LIST_ENTRY *)SplitBlock->HeapEntry.UnpackedEntry.Size;
for( m = v35->ArraySize; (unsigned __int64)Size >= m; m = v58->ArraySize )
{
v58 = v35->ExtendedLookup;
if( !v35->ExtendedLookup )
{
LABEL_84:
v39 = (_LIST_ENTRY *)(v35->ArraySize - 1);
goto LABEL_53;
}
v35 = v35->ExtendedLookup;
}
LABEL_52:
v39 = Size;
LABEL_53:
LODWORD(Param2) = (_DWORD)v39;
RtlpHeapAddListEntry(Heap, v35, v39, (UINT64)p_FreeList, (UINT64)Param2);
}
LABEL_54:
if( Heap->EncodeFlagMask )
{
SplitBlock->HeapEntry.UnpackedEntry.SmallTagIndex = LOBYTE(SplitBlock->InterceptorValue) ^ BYTE1(SplitBlock->Code1) ^ SplitBlock->HeapEntry.UnpackedEntry.Flags;
SplitBlock->HeapEntry.UnpackedEntry.SubSegmentCode ^= Heap->Encoding.UnpackedEntry.SubSegmentCode;
}
return 1;
}
SplitBlock->HeapEntry.UnpackedEntry.Flags &= 0xF0u;
if( (Heap->Flags & 0x40) != 0 )
{
v59 = SplitBlock + 1;
v60 = (16 * (unsigned __int64)(unsigned __int16)FreeSize - 32) >> 2;
if( v60 )
{
if( ((unsigned __int8)v59 & 4) != 0 )
{
--v60;
LODWORD(v59->HeapEntry.UnpackedEntry.PreviousBlockPrivateData) = -17891602;
v59 = (_HEAP_FREE_ENTRY *)((char *)SplitBlock + 36);
}
memset64(v59, 0xFEEEFEEEFEEEFEEEui64, v60 >> 1);
if( (v60 & 1) != 0 )
*((_DWORD *)&v59->HeapEntry.UnpackedEntry + v60 - 1) = -17891602;
}
SplitBlock->HeapEntry.UnpackedEntry.Flags |= 4u;
}
v61 = &Heap->FreeLists;
if( Heap->BlocksIndex )
v62 = RtlpFindEntry(Heap, (unsigned __int16)FreeSize);
else
v62 = v61->Flink;
if( v61 != v62 )
{
v63 = Heap->EncodeFlagMask;
do
{
if( v63 )
{
v64 = (int)v62[-1].Blink;
v63 = Heap->EncodeFlagMask;
LOWORD(v76) = v64;
if( (v63 & v64) != 0 )
v76 = Heap->Encoding.UnpackedEntry.SubSegmentCode ^ v64;
v65 = v76;
}
else
{
v65 = (unsigned __int16)v62[-1].Blink;
}
if( (unsigned __int16)FreeSize <= (unsigned __int64)v65 )
break;
v62 = v62->Flink;
}
while( v61 != v62 );
}
v66 = v62->Blink;
v67 = &SplitBlock->FreeList;
if( v66->Flink == v62 )
{
v67->Flink = v62;
SplitBlock->FreeList.Blink = v66;
v66->Flink = v67;
v62->Blink = v67;
}
else
{
RtlpLogHeapFailure(heap_failure_freelists_corruption, 0i64, v62, 0i64, v66->Flink);
}
Heap->TotalFreeSize += SplitBlock->HeapEntry.UnpackedEntry.Size;
v68 = (_HEAP_LIST_LOOKUP *)Heap->BlocksIndex;
if( v68 )
{
for( n = v68->ArraySize; ; n = v70->ArraySize )
{
if( SplitBlock->HeapEntry.UnpackedEntry.Size < n )
{
v71 = (_LIST_ENTRY *)SplitBlock->HeapEntry.UnpackedEntry.Size;
goto LABEL_137;
}
v70 = v68->ExtendedLookup;
if( !v68->ExtendedLookup )
break;
v68 = v68->ExtendedLookup;
}
v71 = (_LIST_ENTRY *)(v68->ArraySize - 1);
LABEL_137:
LODWORD(Param2) = (_DWORD)v71;
RtlpHeapAddListEntry(Heap, v68, v71, (UINT64)&SplitBlock->FreeList, (UINT64)Param2);
}
if( Heap->EncodeFlagMask )
{
SplitBlock->HeapEntry.UnpackedEntry.SmallTagIndex = LOBYTE(SplitBlock->InterceptorValue) ^ BYTE1(SplitBlock->Code1) ^ SplitBlock->HeapEntry.UnpackedEntry.Flags;
SplitBlock->HeapEntry.UnpackedEntry.SubSegmentCode ^= Heap->Encoding.UnpackedEntry.SubSegmentCode;
}
return 1;
}Referenced by:
RtlpAllocateHeap