What this example does is forcing a split of chunks so a chunk of size 0x20 (smallest) will be inserted to the 0x20 smallbin which is the first one. Then it allocates the biggest chunk that fits smallbin requirments 0x3f0 - 8 so it will be inserted to the 0x3f0 which is the last smallbin.
Afterwards it allocates the smallest chunk that fits largebin requirments 0x3f0 + 1 so it will be inserted to the first largebin.
The calculation problem, lets break into this program at the end of main.
gdb heap_h -x utils.sh
# utils.sh
...
define hip
parseheap
heapinfo
end
...
heapinfo output shows us the "a05" is in the 64th largebin, it should be the 1st (0) in largebins.
Sidenote, both smallbins and largebins are part of a bigger array in "malloc_state" struct called "bins".
This array length is determined at compile time:
gdb-peda$ set $unorderedbin=(long long int)(&main_arena.bins)
gdb-peda$ set $last_smallbin=(long long int)(&main_arena.bins) + 0x10 * 62
gdb-peda$ set $first_largebin=(long long int)(&main_arena.bins) + 0x10 * 63
gdb-peda$ x $unorderedbin
0x7ffff7dd3b68 <main_arena+104>: 0x00007ffff7dd3b58
gdb-peda$ x $last_smallbin
0x7ffff7dd3f48 <main_arena+1096>: 0x00005555557564e0
gdb-peda$ x $first_largebin
0x7ffff7dd3f58 <main_arena+1112>: 0x0000555555756ae0
Analyzing glibc2.24 malloc internals on a 64-bit machine, I'm using both parseheap & heapinfo functionalities.
Basically, when we use heapinfo we get "wrong" index number for largebins. It will be easier to explain with an example.
What this example does is forcing a split of chunks so a chunk of size 0x20 (smallest) will be inserted to the 0x20 smallbin which is the first one. Then it allocates the biggest chunk that fits smallbin requirments 0x3f0 - 8 so it will be inserted to the 0x3f0 which is the last smallbin. Afterwards it allocates the smallest chunk that fits largebin requirments 0x3f0 + 1 so it will be inserted to the first largebin.
The calculation problem, lets break into this program at the end of main. gdb heap_h -x utils.sh
output
heapinfo output shows us the "a05" is in the 64th largebin, it should be the 1st (0) in largebins.
Sidenote, both smallbins and largebins are part of a bigger array in "malloc_state" struct called "bins". This array length is determined at compile time:
The first bin is the unsortedbin, then (in this example) 62 smallbins and the rest should be largebins (63?)..
Example of calculating the last smallbin and first largebin address in malloc_state. Check main_arena (malloc_state) struct
calculate