Ili kuboresha ufanisi wa jinsi chunks zinavyohifadhiwa, kila chunk haiko tu katika orodha moja iliyo na uhusiano, bali kuna aina kadhaa. Hizi ni bins na kuna aina 5 za bins: 62 bins ndogo, 63 bins kubwa, 1 bin isiyo na mpangilio, 10 bins za haraka na 64 bins za tcache kwa kila thread.
Anwani ya awali kwa kila bin isiyo na mpangilio, ndogo na kubwa iko ndani ya array moja. Index 0 haitumiki, 1 ni bin isiyo na mpangilio, bins 2-64 ni bins ndogo na bins 65-127 ni bins kubwa.
Tcache (Per-Thread Cache) Bins
Ingawa nyuzi zinajaribu kuwa na heap yao wenyewe (ona Arenas na Subheaps), kuna uwezekano kwamba mchakato wenye nyuzi nyingi (kama seva ya wavuti) utashiriki heap na nyuzi nyingine. Katika kesi hii, suluhisho kuu ni matumizi ya lockers, ambayo yanaweza kuchelewesha sana nyuzi.
Wakati thread inachomoa chunk, ikiwa si kubwa sana ili iweze kutolewa katika tcache na bin husika ya tcache haiwezi kuwa kamili (tayari chunks 7), itawekwa hapo. Ikiwa haiwezi kuingia kwenye tcache, itahitaji kusubiri kufungwa kwa heap ili iweze kufanya operesheni ya kuachilia kimataifa.
Wakati chunk inatolewa, ikiwa kuna chunk ya bure ya saizi inayohitajika katika Tcache itaitumia, ikiwa sivyo, itahitaji kusubiri kufungwa kwa heap ili iweze kupata moja katika bins za kimataifa au kuunda mpya.
Pia kuna uboreshaji, katika kesi hii, wakati wa kuwa na kufungwa kwa heap, thread itajaza Tcache yake na chunks za heap (7) za saizi iliyohitajika, hivyo ikiwa inahitaji zaidi, itazipata katika Tcache.
Add a tcache chunk example
```c #include #include
int main(void) { char *chunk; chunk = malloc(24); printf("Address of the chunk: %p\n", (void *)chunk); gets(chunk); free(chunk); return 0; }
Kusanya na kukarabati na breakpoint katika opcode ya ret kutoka kwa kazi ya main. Kisha kwa gef unaweza kuona tcache bin inatumika:
```bash
gef➤ heap bins
──────────────────────────────────────────────────────────────────────────────── Tcachebins for thread 1 ────────────────────────────────────────────────────────────────────────────────
Tcachebins[idx=0, size=0x20, count=1] ← Chunk(addr=0xaaaaaaac12a0, size=0x20, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA)
Tcache Structs & Functions
Katika msimbo ufuatao inawezekana kuona max bins na chunks per index, muundo wa tcache_entry ulioandaliwa ili kuepuka uhuru mara mbili na tcache_perthread_struct, muundo ambao kila thread inatumia kuhifadhi anwani za kila index ya bin.
tcache_entry na tcache_perthread_struct
```c // From https://github.com/bminor/glibc/blob/f942a732d37a96217ef828116ebe64a644db18d7/malloc/malloc.c
/* We want 64 entries. This is an arbitrary limit, which tunables can reduce. */
/* With rounding and alignment, the bins are... idx 0 bytes 0..24 (64-bit) or 0..12 (32-bit) idx 1 bytes 25..40 or 13..20 idx 2 bytes 41..56 or 21..28 etc. */
/* This is another arbitrary limit, which tunables can change. Each tcache bin will hold at most this number of chunks. */
define TCACHE_FILL_COUNT 7
/* Maximum chunks in tcache bins for tunables. This value must fit the range of tcache->counts[] entries, else they may overflow. */
define MAX_TCACHE_COUNT UINT16_MAX
[...]
typedef struct tcache_entry { struct tcache_entry next; / This field exists to detect double frees. */ uintptr_t key; } tcache_entry;
/* There is one of these for each thread, which contains the per-thread cache (hence "tcache_perthread_struct"). Keeping overall size low is mildly important. Note that COUNTS and ENTRIES are redundant (we could have just counted the linked list each time), this is for performance reasons. */ typedef struct tcache_perthread_struct { uint16_t counts[TCACHE_MAX_BINS]; tcache_entry *entries[TCACHE_MAX_BINS]; } tcache_perthread_struct;
</details>
Kazi ya `__tcache_init` ni kazi inayounda na kugawa nafasi kwa ajili ya `tcache_perthread_struct` obj
<details>
<summary>tcache_init code</summary>
```c
// From https://github.com/bminor/glibc/blob/f942a732d37a96217ef828116ebe64a644db18d7/malloc/malloc.c#L3241C1-L3274C2
static void
tcache_init(void)
{
mstate ar_ptr;
void *victim = 0;
const size_t bytes = sizeof (tcache_perthread_struct);
if (tcache_shutting_down)
return;
arena_get (ar_ptr, bytes);
victim = _int_malloc (ar_ptr, bytes);
if (!victim && ar_ptr != NULL)
{
ar_ptr = arena_get_retry (ar_ptr, bytes);
victim = _int_malloc (ar_ptr, bytes);
}
if (ar_ptr != NULL)
__libc_lock_unlock (ar_ptr->mutex);
/* In a low memory situation, we may not be able to allocate memory
- in which case, we just keep trying later. However, we
typically do this very early, so either there is sufficient
memory, or there isn't enough memory to do non-trivial
allocations anyway. */
if (victim)
{
tcache = (tcache_perthread_struct *) victim;
memset (tcache, 0, sizeof (tcache_perthread_struct));
}
}
Tcache Indexes
Tcache ina bins kadhaa kulingana na saizi na viashiria vya awali kwa kipande cha kwanza cha kila index na kiasi cha vipande kwa index vinapatikana ndani ya kipande. Hii inamaanisha kwamba kutafuta kipande chenye taarifa hii (kawaida kipande cha kwanza), inawezekana kupata viashiria vyote vya tcache na kiasi cha vipande vya Tcache.
Fast bins
Fast bins zimeundwa ili kuharakisha ugawaji wa kumbukumbu kwa vipande vidogo kwa kuweka vipande vilivyofutwa hivi karibuni katika muundo wa upatikanaji wa haraka. Bins hizi zinatumia mbinu ya Last-In, First-Out (LIFO), ambayo inamaanisha kwamba kipande kilichofutwa hivi karibuni ndicho cha kwanza kutumika tena wakati kuna ombi jipya la ugawaji. Tabia hii ni ya faida kwa kasi, kwani ni haraka zaidi kuingiza na kuondoa kutoka juu ya stack (LIFO) ikilinganishwa na foleni (FIFO).
Zaidi ya hayo, fast bins zinatumia orodha zilizounganishwa kwa njia moja, si mbili, ambayo inaboresha zaidi kasi. Kwa kuwa vipande katika fast bins havijachanganywa na majirani, hakuna haja ya muundo mgumu unaoruhusu kuondoa kutoka katikati. Orodha iliyo na uhusiano mmoja ni rahisi na haraka kwa shughuli hizi.
Kimsingi, kinachotokea hapa ni kwamba kichwa (kiashiria kwa kipande cha kwanza cha kuangalia) daima kinaelekeza kwenye kipande kilichofutwa hivi karibuni cha saizi hiyo. Hivyo:
Wakati kipande kipya kinapogawiwa cha saizi hiyo, kichwa kinaelekeza kwenye kipande cha bure cha kutumia. Kwa kuwa kipande hiki cha bure kinaelekeza kwenye kipande kinachofuata kutumia, anwani hii inahifadhiwa katika kichwa ili ugawaji ujao ujue wapi kupata kipande kilichopatikana
Wakati kipande kinapofutwa, kipande cha bure kitahifadhi anwani ya kipande kilichopatikana kwa sasa na anwani ya kipande hiki kilichofutwa hivi karibuni itawekwa katika kichwa
Saizi ya juu ya orodha iliyo na uhusiano ni 0x80 na zimeandaliwa hivyo kwamba kipande cha saizi 0x20 kitakuwa katika index 0, kipande cha saizi 0x30 kitakuwa katika index 1...
Vipande katika fast bins havijapangwa kama vinapatikana hivyo vinahifadhiwa kama vipande vya fast bin kwa muda badala ya kuwa na uwezo wa kuchanganyika na vipande vingine vya bure vinavyovizunguka.
// From https://github.com/bminor/glibc/blob/a07e000e82cb71238259e674529c37c12dc7d423/malloc/malloc.c#L1711/*FastbinsAn array of lists holding recently freed small chunks. Fastbinsare not doubly linked. It is faster to single-link them, andsince chunks are never removed from the middles of these lists,double linking is not necessary. Also, unlike regular bins, theyare not even processed in FIFO order (they use faster LIFO) sinceordering doesn't much matter in the transient contexts in whichfastbins are normally used.Chunks in fastbins keep their inuse bit set, so they cannotbe consolidated with other free chunks. malloc_consolidatereleases all chunks in fastbins and consolidates them withother free chunks.*/typedefstruct malloc_chunk *mfastbinptr;#definefastbin(ar_ptr, idx) ((ar_ptr)->fastbinsY[idx])/* offset 2 to use otherwise unindexable first 2 bins */#definefastbin_index(sz) \((((unsignedint) (sz)) >> (SIZE_SZ ==8?4:3)) -2)/* The maximum fastbin request size we support */#defineMAX_FAST_SIZE (80* SIZE_SZ /4)#defineNFASTBINS (fastbin_index (request2size (MAX_FAST_SIZE)) +1)
Ongeza mfano wa fastbin chunk
```c #include #include
int main(void) { char *chunks[8]; int i;
// Loop to allocate memory 8 times for (i = 0; i < 8; i++) { chunks[i] = malloc(24); if (chunks[i] == NULL) { // Check if malloc failed fprintf(stderr, "Memory allocation failed at iteration %d\n", i); return 1; } printf("Address of chunk %d: %p\n", i, (void *)chunks[i]); }
// Loop to free the allocated memory for (i = 0; i < 8; i++) { free(chunks[i]); }
return 0; }
Kumbuka jinsi tunavyopanga na kuachilia vipande 8 vya saizi sawa ili vijaze tcache na kipande cha nane kikiwa kimehifadhiwa katika fast chunk.
Kusanya na kufanyia debug na breakpoint katika opcode ya `ret` kutoka kwa kazi ya `main`. Kisha kwa kutumia `gef` unaweza kuona kwamba tcache bin imejaa na kipande kimoja kiko katika fast bin:
```bash
gef➤ heap bins
──────────────────────────────────────────────────────────────────────────────── Tcachebins for thread 1 ────────────────────────────────────────────────────────────────────────────────
Tcachebins[idx=0, size=0x20, count=7] ← Chunk(addr=0xaaaaaaac1770, size=0x20, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA) ← Chunk(addr=0xaaaaaaac1750, size=0x20, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA) ← Chunk(addr=0xaaaaaaac1730, size=0x20, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA) ← Chunk(addr=0xaaaaaaac1710, size=0x20, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA) ← Chunk(addr=0xaaaaaaac16f0, size=0x20, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA) ← Chunk(addr=0xaaaaaaac16d0, size=0x20, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA) ← Chunk(addr=0xaaaaaaac12a0, size=0x20, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA)
───────────────────────────────────────────────────────────────────────── Fastbins for arena at 0xfffff7f90b00 ─────────────────────────────────────────────────────────────────────────
Fastbins[idx=0, size=0x20] ← Chunk(addr=0xaaaaaaac1790, size=0x20, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA)
Fastbins[idx=1, size=0x30] 0x00
Unsorted bin
Bin isiyo na mpangilio ni cache inayotumiwa na meneja wa heap kufanya ugawaji wa kumbukumbu kuwa wa haraka. Hapa kuna jinsi inavyofanya kazi: Wakati programu inapoachia kipande, na ikiwa kipande hiki hakiwezi kugawanywa katika tcache au fast bin na hakigongani na kipande cha juu, meneja wa heap haweka mara moja katika bin maalum ndogo au kubwa. Badala yake, kwanza hujaribu kuunganisha na kipande chochote cha jirani kilichopatikana ili kuunda block kubwa ya kumbukumbu isiyopatikana. Kisha, huweka kipande hiki kipya katika bin ya jumla inayoitwa "unsorted bin."
Wakati programu inapohitaji kumbukumbu, meneja wa heap anachunguza bin isiyo na mpangilio kuona kama kuna kipande cha ukubwa wa kutosha. Ikiwa anakipata, anakitumia mara moja. Ikiwa hakupata kipande kinachofaa katika bin isiyo na mpangilio, anahamisha vipande vyote katika orodha hii kwenye bins zao zinazofaa, ama ndogo au kubwa, kulingana na ukubwa wao.
Kumbuka kwamba ikiwa kipande kikubwa kinagawanywa katika nusu 2 na kilichobaki ni kikubwa kuliko MINSIZE, kitarejeshwa tena katika bin isiyo na mpangilio.
Hivyo, bin isiyo na mpangilio ni njia ya kuongeza kasi ya ugawaji wa kumbukumbu kwa haraka kurudisha kumbukumbu iliyokuwa imeachwa hivi karibuni na kupunguza hitaji la utafutaji na kuunganishwa kwa muda mrefu.
Kumbuka kwamba hata kama vipande ni vya makundi tofauti, ikiwa kipande kinachopatikana kinagongana na kipande kingine kinachopatikana (hata kama vilikuwa na asili tofauti katika bins tofauti), vitaundwa pamoja.
Ongeza mfano wa kipande kisichopangwa
```c #include #include
int main(void) { char *chunks[9]; int i;
// Loop to allocate memory 8 times for (i = 0; i < 9; i++) { chunks[i] = malloc(0x100); if (chunks[i] == NULL) { // Check if malloc failed fprintf(stderr, "Memory allocation failed at iteration %d\n", i); return 1; } printf("Address of chunk %d: %p\n", i, (void *)chunks[i]); }
// Loop to free the allocated memory for (i = 0; i < 8; i++) { free(chunks[i]); }
return 0; }
Note jinsi tunavyopanga na kuachilia vipande 9 vya saizi sawa ili **kujaza tcache** na ile ya nane inahifadhiwa katika bin isiyo na mpangilio kwa sababu ni **kubwa sana kwa fastbin** na ile ya tisa haijaachiliwa hivyo ile ya tisa na ya nane **hazijachanganywa na kipande cha juu**.
Ili kuunda na ku-debug na breakpoint katika opcode ya `ret` kutoka kwa kazi ya `main`. Kisha kwa kutumia `gef` unaweza kuona kwamba bin ya tcache imejaa na kipande kimoja kiko katika bin isiyo na mpangilio:
```bash
gef➤ heap bins
──────────────────────────────────────────────────────────────────────────────── Tcachebins for thread 1 ────────────────────────────────────────────────────────────────────────────────
Tcachebins[idx=15, size=0x110, count=7] ← Chunk(addr=0xaaaaaaac1d10, size=0x110, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA) ← Chunk(addr=0xaaaaaaac1c00, size=0x110, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA) ← Chunk(addr=0xaaaaaaac1af0, size=0x110, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA) ← Chunk(addr=0xaaaaaaac19e0, size=0x110, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA) ← Chunk(addr=0xaaaaaaac18d0, size=0x110, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA) ← Chunk(addr=0xaaaaaaac17c0, size=0x110, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA) ← Chunk(addr=0xaaaaaaac12a0, size=0x110, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA)
───────────────────────────────────────────────────────────────────────── Fastbins for arena at 0xfffff7f90b00 ─────────────────────────────────────────────────────────────────────────
Fastbins[idx=0, size=0x20] 0x00
Fastbins[idx=1, size=0x30] 0x00
Fastbins[idx=2, size=0x40] 0x00
Fastbins[idx=3, size=0x50] 0x00
Fastbins[idx=4, size=0x60] 0x00
Fastbins[idx=5, size=0x70] 0x00
Fastbins[idx=6, size=0x80] 0x00
─────────────────────────────────────────────────────────────────────── Unsorted Bin for arena at 0xfffff7f90b00 ───────────────────────────────────────────────────────────────────────
[+] unsorted_bins[0]: fw=0xaaaaaaac1e10, bk=0xaaaaaaac1e10
→ Chunk(addr=0xaaaaaaac1e20, size=0x110, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA)
[+] Found 1 chunks in unsorted bin.
Small Bins
Small bins ni haraka zaidi kuliko large bins lakini polepole zaidi kuliko fast bins.
Kila bin ya 62 itakuwa na chunks za saizi sawa: 16, 24, ... (ikiwa na saizi ya juu ya 504 bytes katika 32bits na 1024 katika 64bits). Hii inasaidia katika kasi ya kutafuta bin ambapo nafasi inapaswa kutolewa na kuingiza na kuondoa entries kwenye orodha hizi.
Hivi ndivyo saizi ya small bin inavyokadiriwa kulingana na index ya bin:
Saizi ndogo zaidi: 2*4*index (mfano: index 5 -> 40)
Saizi kubwa zaidi: 2*8*index (mfano: index 5 -> 80)
// Loop to allocate memory 8 times for (i = 0; i < 9; i++) { chunks[i] = malloc(0x100); if (chunks[i] == NULL) { // Check if malloc failed fprintf(stderr, "Memory allocation failed at iteration %d\n", i); return 1; } printf("Address of chunk %d: %p\n", i, (void *)chunks[i]); }
// Loop to free the allocated memory for (i = 0; i < 8; i++) { free(chunks[i]); }
chunks[9] = malloc(0x110);
return 0; }
Note how we allocate and free 9 chunks of the same size so they **fill the tcache** and the eight one is stored in the unsorted bin because it's **too big for the fastbin** and the ninth one isn't freed so the ninth and the eights **don't get merged with the top chunk**. Then we allocate a bigger chunk of 0x110 which makes **the chunk in the unsorted bin goes to the small bin**.
Compile it and debug it with a breakpoint in the `ret` opcode from `main` function. then with `gef` you can see that the tcache bin is full and one chunk is in the small bin:
```bash
gef➤ heap bins
──────────────────────────────────────────────────────────────────────────────── Tcachebins for thread 1 ────────────────────────────────────────────────────────────────────────────────
Tcachebins[idx=15, size=0x110, count=7] ← Chunk(addr=0xaaaaaaac1d10, size=0x110, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA) ← Chunk(addr=0xaaaaaaac1c00, size=0x110, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA) ← Chunk(addr=0xaaaaaaac1af0, size=0x110, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA) ← Chunk(addr=0xaaaaaaac19e0, size=0x110, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA) ← Chunk(addr=0xaaaaaaac18d0, size=0x110, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA) ← Chunk(addr=0xaaaaaaac17c0, size=0x110, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA) ← Chunk(addr=0xaaaaaaac12a0, size=0x110, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA)
───────────────────────────────────────────────────────────────────────── Fastbins for arena at 0xfffff7f90b00 ─────────────────────────────────────────────────────────────────────────
Fastbins[idx=0, size=0x20] 0x00
Fastbins[idx=1, size=0x30] 0x00
Fastbins[idx=2, size=0x40] 0x00
Fastbins[idx=3, size=0x50] 0x00
Fastbins[idx=4, size=0x60] 0x00
Fastbins[idx=5, size=0x70] 0x00
Fastbins[idx=6, size=0x80] 0x00
─────────────────────────────────────────────────────────────────────── Unsorted Bin for arena at 0xfffff7f90b00 ───────────────────────────────────────────────────────────────────────
[+] Found 0 chunks in unsorted bin.
──────────────────────────────────────────────────────────────────────── Small Bins for arena at 0xfffff7f90b00 ────────────────────────────────────────────────────────────────────────
[+] small_bins[16]: fw=0xaaaaaaac1e10, bk=0xaaaaaaac1e10
→ Chunk(addr=0xaaaaaaac1e20, size=0x110, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA)
[+] Found 1 chunks in 1 small non-empty bins.
Large bins
Kinyume na bins ndogo, ambazo husimamia vipande vya saizi thabiti, kila large bin inashughulikia anuwai ya saizi za vipande. Hii ni rahisi zaidi, ikiruhusu mfumo kubeba saizi mbalimbali bila kuhitaji bin tofauti kwa kila saizi.
Katika mtoa huduma wa kumbukumbu, large bins huanza pale bins ndogo zinapomalizika. Mipaka ya large bins inakua kwa kiwango cha juu, ikimaanisha bin ya kwanza inaweza kufunika vipande kutoka 512 hadi 576 bytes, wakati inayofuata inafunika 576 hadi 640 bytes. Mwelekeo huu unaendelea, huku bin kubwa zaidi ikijumuisha vipande vyote vya juu ya 1MB.
Large bins ni polepole kufanya kazi ikilinganishwa na bins ndogo kwa sababu lazima zipange na kutafuta kupitia orodha ya saizi tofauti za vipande ili kupata inayofaa zaidi kwa ugawaji. Wakati kipande kinapowekwa kwenye large bin, kinapaswa kupangwa, na wakati kumbukumbu inatolewa, mfumo lazima upate kipande sahihi. Kazi hii ya ziada inafanya kuwa polepole, lakini kwa kuwa ugawaji mkubwa ni nadra zaidi kuliko mdogo, ni kubadilishana kukubalika.
Kuna:
32 bins za 64B anuwai (zinagongana na bins ndogo)
16 bins za 512B anuwai (zinagongana na bins ndogo)
8 bins za 4096B anuwai (sehemu zinagongana na bins ndogo)
4 bins za 32768B anuwai
2 bins za 262144B anuwai
1 bin kwa saizi zilizobaki
Large bin sizes code
```c // From https://github.com/bminor/glibc/blob/a07e000e82cb71238259e674529c37c12dc7d423/malloc/malloc.c#L1711
</details>
<details>
<summary>Ongeza mfano wa kipande kikubwa</summary>
```c
#include <stdlib.h>
#include <stdio.h>
int main(void)
{
char *chunks[2];
chunks[0] = malloc(0x1500);
chunks[1] = malloc(0x1500);
free(chunks[0]);
chunks[0] = malloc(0x2000);
return 0;
}
2 allocations kubwa zinafanywa, kisha moja inachukuliwa (ikiweka kwenye bin isiyo na mpangilio) na allocation kubwa zaidi inafanywa (ikihamasisha ile iliyochukuliwa kutoka kwenye bin isiyo na mpangilio hadi kwenye bin kubwa).
Ili compile na debug na breakpoint katika opcode ya ret kutoka kwa kazi ya main. Kisha kwa kutumia gef unaweza kuona kwamba bin ya tcache imejaa na kipande kimoja kiko kwenye bin kubwa:
gef➤heapbin────────────────────────────────────────────────────────────────────────────────Tcachebinsforthread1────────────────────────────────────────────────────────────────────────────────Alltcachebinsareempty─────────────────────────────────────────────────────────────────────────Fastbinsforarenaat0xfffff7f90b00─────────────────────────────────────────────────────────────────────────Fastbins[idx=0,size=0x20]0x00Fastbins[idx=1,size=0x30]0x00Fastbins[idx=2,size=0x40]0x00Fastbins[idx=3,size=0x50]0x00Fastbins[idx=4,size=0x60]0x00Fastbins[idx=5,size=0x70]0x00Fastbins[idx=6,size=0x80]0x00───────────────────────────────────────────────────────────────────────UnsortedBinforarenaat0xfffff7f90b00───────────────────────────────────────────────────────────────────────[+] Found 0 chunks in unsorted bin.────────────────────────────────────────────────────────────────────────SmallBinsforarenaat0xfffff7f90b00────────────────────────────────────────────────────────────────────────[+] Found 0 chunks in 0 small non-empty bins.────────────────────────────────────────────────────────────────────────LargeBinsforarenaat0xfffff7f90b00────────────────────────────────────────────────────────────────────────[+] large_bins[100]: fw=0xaaaaaaac1290, bk=0xaaaaaaac1290→Chunk(addr=0xaaaaaaac12a0, size=0x1510, flags=PREV_INUSE|IS_MMAPPED|NON_MAIN_ARENA)[+] Found 1 chunks in 1 large non-empty bins.
Sehemu Kuu
// From https://github.com/bminor/glibc/blob/a07e000e82cb71238259e674529c37c12dc7d423/malloc/malloc.c#L1711/*TopThe top-most available chunk (i.e., the one bordering the end ofavailable memory) is treated specially. It is never included inany bin, is used only if no other chunk is available, and isreleased back to the system if it is very large (seeM_TRIM_THRESHOLD). Because top initiallypoints to its own bin with initial zero size, thus forcingextension on the first malloc request, we avoid having any specialcode in malloc to check whether it even exists yet. But we stillneed to do so when getting memory from system, so we makeinitial_top treat the bin as a legal but unusable chunk during theinterval between initialization and the first call tosysmalloc. (This is somewhat delicate, since it relies onthe 2 preceding words to be zero during this interval as well.)*//* Conveniently, the unsorted bin can be used as dummy top on first call */#defineinitial_top(M) (unsorted_chunks (M))
Mahali ambapo inaonekana kwamba kipande cha juu kiko kwenye anwani 0xaaaaaaac1ae0. Hii si ajabu kwa sababu kipande cha mwisho kilichotengwa kilikuwa kwenye 0xaaaaaaac12a0 chenye ukubwa wa 0x410 na 0xaaaaaaac12a0 + 0x410 = 0xaaaaaaac1ae0.
Pia inawezekana kuona urefu wa kipande cha Juu kwenye kichwa chake:
Wakati malloc inatumika na kipande kinagawanywa (kutoka kwenye bin isiyo na mpangilio au kutoka kwenye kipande cha juu kwa mfano), kipande kilichoundwa kutoka kwa sehemu iliyogawanywa kinaitwa Kumbukumbu ya Mwisho na kiashiria chake kinahifadhiwa katika muundo wa malloc_state.
Mchakato wa Ugawaji
Angalia:
Mchakato wa Kuachilia
Angalia:
Ukaguzi wa Usalama wa Kazi za Heap
Angalia ukaguzi wa usalama unaofanywa na kazi zinazotumika sana katika heap katika: