Heap Basics
Understanding the basics of the heap
Last updated
Understanding the basics of the heap
Last updated
Malloc Structure
The important thing is how the chunk's user
data section contains fd
and bk
pointers to other free chunks which is usually exploited
Example - Allocated Chunk
Example - Freed Chunk
On x64
systems, the heap chunk header is a size of 0x10
bytes and 0x8
on x32.
When a chunk is freed, it will usually insert it in one of the bin lists. Upon another allocation, the heap will see if there are bins that fit the size required that could be reused for memory efficiency.
Fast Bins
0x20 - 0x80
Consist of 7 linked lists referred to by their idx
Uses LIFO
Usually the first list libc looks at (if tcache is not available)
Tcache Bins
0x18 - 0x408 (x64) 0xC - 0x204 (x32)
Similar to fastbins but faster, thread specific. Can only hold 7 chunks at a specific time, will use other bins if full
Unsorted Bins
Cache used to make memory allocation quicker
When a program frees a chunk and chunk cannot be allocated in a tcache or fast bin and is not colliding with the top chunk (holds the large unallocated data)
It first tries to merge it with any neighbouring free chunks to create a larger block of free memory. Then, it places this new chunk in a general bin called the "unsorted bin" -> will be useful later for libc leaks
To prevent consolidation with top chunk, allocate a small chunk in between our freed chunks and the top chunk, just to prevent that consolidation.
Allocation Order
__libc_malloc
tries to get a chunk from the tcache, if not it calls _int_malloc
_int_malloc
:
Tries to generate the arena if there isn't any
If any fast bin chunk of the correct size, use it
Fill tcache with other fast chunks
If any small bin chunk of the correct size, use it
Fill tcache with other chunks of that size
If the requested size isn't for small bins, consolidate fast bin into unsorted bin
Check the unsorted bin, use the first chunk with enough space
If the found chunk is bigger, divide it to return a part and add the reminder back to the unsorted bin
If a chunk is of the same size as the size requested, use to to fill the tcache instead of returning it (until the tcache is full, then return the next one)
For each chunk of smaller size checked, put it in its respective small or large bin
Check the large bin in the index of the requested size
Start looking from the first chunk that is bigger than the requested size, if any is found return it and add the reminders to the small bin
Check the large bins from the next indexes until the end
From the next bigger index check for any chunk, divide the first found chunk to use it for the requested size and add the reminder to the unsorted bin
If nothing is found in the previous bins, get a chunk from the top chunk
If the top chunk wasn't big enough enlarge it with sysmalloc
Free Order
If the address is null don't do anything
If the chunk was mmaped, mummap it and finish
Call _int_free
:
If possible, add the chunk to the tcache
If possible, add the chunk to the fast bin
Call _int_free_merge_chunk
to consolidate the chunk is needed and add it to the unsorted list
Copied from here