Libc Heap

Heap Temelleri

Heap, temelde bir programın malloc, calloc gibi fonksiyonları çağırarak veri talep ettiğinde verileri depolayabileceği yerdir. Ayrıca, bu bellek artık gerekli olmadığında free fonksiyonu çağrılarak kullanılabilir hale getirilir.

Görüldüğü gibi, bu bellek, ikili dosyanın belleğe yüklendiği yerin hemen sonrasındadır (bakınız [heap] bölümü):

Temel Chunk Tahsisi

Heap'te depolanması istenen bazı veriler için heap'ten bir alan tahsis edilir. Bu alan bir bin'e ait olacak ve yalnızca istenen veri + bin başlıklarının alanı + minimum bin boyutu ofseti chunk için ayrılacaktır. Amaç, her chunk'ın nerede olduğunu bulmayı karmaşık hale getirmeden mümkün olan en az bellek ayırmaktır. Bunun için, her kullanılan/boş chunk'ın nerede olduğunu bilmek için metadata chunk bilgisi kullanılır.

Alanı ayırmanın farklı yolları vardır, esasen kullanılan bin'e bağlıdır, ancak genel bir metodoloji şudur:

  • Program belirli bir miktar bellek talep ederek başlar.

  • Eğer chunk listesinde talebi karşılayacak kadar büyük bir alan varsa, bu kullanılacaktır.

  • Bu, mevcut chunk'ın bir kısmının bu talep için kullanılacağı ve geri kalanının chunk listesine ekleneceği anlamına gelebilir.

  • Eğer listede mevcut bir chunk yoksa ancak tahsis edilmiş heap belleğinde hala alan varsa, heap yöneticisi yeni bir chunk oluşturur.

  • Eğer yeni chunk'ı tahsis etmek için yeterli heap alanı yoksa, heap yöneticisi çekirdekten heap'e tahsis edilen belleği genişletmesini ister ve ardından bu belleği yeni chunk'ı oluşturmak için kullanır.

  • Her şey başarısız olursa, malloc null döner.

Talep edilen bellek bir eşiği geçerse, mmap talep edilen belleği haritalamak için kullanılacaktır.

Arenalar

Çok iş parçacıklı uygulamalarda, heap yöneticisi çöküşe yol açabilecek yarış koşullarını önlemelidir. Başlangıçta, yalnızca bir iş parçacığının heap'e erişebilmesini sağlamak için küresel bir mutex kullanılıyordu, ancak bu mutex kaynaklı darboğaz nedeniyle performans sorunlarına yol açtı.

Bunu çözmek için, ptmalloc2 heap tahsis edici "arenalar" tanıttı; burada her arena, kendi veri yapıları ve mutex ile ayrı bir heap olarak işlev görür ve farklı arenaları kullandıkları sürece birden fazla iş parçacığının heap işlemleri gerçekleştirmesine olanak tanır.

Varsayılan "ana" arena, tek iş parçacıklı uygulamalar için heap işlemlerini yönetir. Yeni iş parçacıkları eklendiğinde, heap yöneticisi bunlara ikincil arenalar atar ve rekabeti azaltır. İlk olarak, her yeni iş parçacığını kullanılmayan bir arenaya bağlamaya çalışır, gerekirse yeni arenalar oluşturur; bu, 32-bit sistemler için CPU çekirdeklerinin sayısının 2 katı ve 64-bit sistemler için 8 katı ile sınırlıdır. Sınır aşıldığında, iş parçacıkları arenaları paylaşmak zorundadır, bu da potansiyel rekabete yol açar.

Ana arenanın brk sistem çağrısını kullanarak genişlemesinin aksine, ikincil arenalar mmap ve mprotect kullanarak "alt heap'ler" oluşturur ve çok iş parçacıklı işlemler için bellek yönetiminde esneklik sağlar.

Alt Heap'ler

Alt heap'ler, çok iş parçacıklı uygulamalarda ikincil arenalar için bellek rezervleri olarak hizmet eder ve ana heap'ten ayrı olarak kendi heap bölgelerini büyütmelerine ve yönetmelerine olanak tanır. İşte alt heap'lerin başlangıç heap'inden nasıl farklılaştığı ve nasıl çalıştığı:

  1. Başlangıç Heap'i vs. Alt Heap'ler:

  • Başlangıç heap'i, programın ikili dosyasının bellekte hemen arkasında yer alır ve sbrk sistem çağrısını kullanarak genişler.

  • İkincil arenalar tarafından kullanılan alt heap'ler, belirli bir bellek bölgesini haritalayan mmap aracılığıyla oluşturulur.

  1. mmap ile Bellek Rezervasyonu:

  • Heap yöneticisi bir alt heap oluşturduğunda, mmap aracılığıyla büyük bir bellek bloğu rezerve eder. Bu rezervasyon hemen bellek tahsis etmez; yalnızca diğer sistem süreçlerinin veya tahsislerin kullanmaması gereken bir bölgeyi belirler.

  • Varsayılan olarak, bir alt heap için rezerve edilen boyut 32-bit süreçler için 1 MB ve 64-bit süreçler için 64 MB'dır.

  1. mprotect ile Aşamalı Genişleme:

  • Rezerve edilen bellek bölgesi başlangıçta PROT_NONE olarak işaretlenir; bu, çekirdeğin bu alana fiziksel bellek tahsis etmesi gerekmediğini gösterir.

  • Alt heap'i "büyütmek" için, heap yöneticisi mprotect kullanarak sayfa izinlerini PROT_NONE'dan PROT_READ | PROT_WRITE'a değiştirir ve bu, çekirdeğin daha önce rezerve edilen adreslere fiziksel bellek tahsis etmesini sağlar. Bu adım adım yaklaşım, alt heap'in gerektiği gibi genişlemesine olanak tanır.

  • Tüm alt heap tükendiğinde, heap yöneticisi tahsise devam etmek için yeni bir alt heap oluşturur.

heap_info

Bu yapı, heap'in ilgili bilgilerini tahsis eder. Ayrıca, daha fazla tahsisten sonra heap belleği kesintili olmayabilir; bu yapı aynı zamanda bu bilgiyi de saklayacaktır.

// From https://github.com/bminor/glibc/blob/a07e000e82cb71238259e674529c37c12dc7d423/malloc/arena.c#L837

typedef struct _heap_info
{
mstate ar_ptr; /* Arena for this heap. */
struct _heap_info *prev; /* Previous heap. */
size_t size;   /* Current size in bytes. */
size_t mprotect_size; /* Size in bytes that has been mprotected
PROT_READ|PROT_WRITE.  */
size_t pagesize; /* Page size used when allocating the arena.  */
/* Make sure the following data is properly aligned, particularly
that sizeof (heap_info) + 2 * SIZE_SZ is a multiple of
MALLOC_ALIGNMENT. */
char pad[-3 * SIZE_SZ & MALLOC_ALIGN_MASK];
} heap_info;

malloc_state

Her heap (ana arena veya diğer thread arenaları) bir malloc_state yapısına sahiptir. Ana arena malloc_state yapısının libc'de global bir değişken olduğunu belirtmek önemlidir (bu nedenle libc bellek alanında yer alır). Thread'lerin heap'lerinin malloc_state yapıları ise kendi thread "heap"lerinin içinde yer alır.

Bu yapıdan bazı ilginç noktalar vardır (aşağıdaki C koduna bakın):

  • __libc_lock_define (, mutex); Bu yapıdan heap'e erişimin aynı anda 1 thread tarafından yapılmasını sağlamak için vardır.

  • Bayraklar:

#define NONCONTIGUOUS_BIT (2U)

#define contiguous(M) (((M)->flags & NONCONTIGUOUS_BIT) == 0) #define noncontiguous(M) (((M)->flags & NONCONTIGUOUS_BIT) != 0) #define set_noncontiguous(M) ((M)->flags |= NONCONTIGUOUS_BIT) #define set_contiguous(M) ((M)->flags &= ~NONCONTIGUOUS_BIT)

* `mchunkptr bins[NBINS * 2 - 2];` **küçük, büyük ve sıralanmamış** **bins**'lerin **ilk ve son chunk'larına** **işaretçiler** içerir (0 indeksinin kullanılmadığı için -2).
* Bu nedenle, bu bins'lerin **ilk chunk'ı** bu yapıya **geriye işaret eden bir işaretçi** ve bu bins'lerin **son chunk'ı** bu yapıya **ileri işaretçi** bulunduracaktır. Bu, eğer **ana arenada bu adresleri sızdırabilirseniz** yapıya bir işaretçi elde edeceğiniz anlamına gelir. 
* `struct malloc_state *next;` ve `struct malloc_state *next_free;` yapıları arena'ların bağlı listeleridir.
* `top` chunk, temelde **tüm heap hatırlatma alanı** olan son "chunk"tır. `top` chunk "boş" olduğunda, heap tamamen kullanılmıştır ve daha fazla alan talep etmesi gerekir.
* `last reminder` chunk, tam boyutlu bir chunk mevcut olmadığında ve bu nedenle daha büyük bir chunk bölündüğünde ortaya çıkar; burada kalan kısmın işaretçisi yer alır.
```c
// From https://github.com/bminor/glibc/blob/a07e000e82cb71238259e674529c37c12dc7d423/malloc/malloc.c#L1812

struct malloc_state
{
/* Serialize access.  */
__libc_lock_define (, mutex);

/* Flags (formerly in max_fast).  */
int flags;

/* Set if the fastbin chunks contain recently inserted free blocks.  */
/* Note this is a bool but not all targets support atomics on booleans.  */
int have_fastchunks;

/* Fastbins */
mfastbinptr fastbinsY[NFASTBINS];

/* Base of the topmost chunk -- not otherwise kept in a bin */
mchunkptr top;

/* The remainder from the most recent split of a small request */
mchunkptr last_remainder;

/* Normal bins packed as described above */
mchunkptr bins[NBINS * 2 - 2];

/* Bitmap of bins */
unsigned int binmap[BINMAPSIZE];

/* Linked list */
struct malloc_state *next;

/* Linked list for free arenas.  Access to this field is serialized
by free_list_lock in arena.c.  */
struct malloc_state *next_free;

/* Number of threads attached to this arena.  0 if the arena is on
the free list.  Access to this field is serialized by
free_list_lock in arena.c.  */
INTERNAL_SIZE_T attached_threads;

/* Memory allocated from the system in this arena.  */
INTERNAL_SIZE_T system_mem;
INTERNAL_SIZE_T max_system_mem;
};

malloc_chunk

Bu yapı, belirli bir bellek parçasını temsil eder. Farklı alanlar, tahsis edilmiş ve tahsis edilmemiş parçalar için farklı anlamlara sahiptir.

// https://github.com/bminor/glibc/blob/master/malloc/malloc.c
struct malloc_chunk {
INTERNAL_SIZE_T      mchunk_prev_size;  /* Size of previous chunk, if it is free. */
INTERNAL_SIZE_T      mchunk_size;       /* Size in bytes, including overhead. */
struct malloc_chunk* fd;                /* double links -- used only if this chunk is free. */
struct malloc_chunk* bk;
/* Only used for large blocks: pointer to next larger size.  */
struct malloc_chunk* fd_nextsize; /* double links -- used only if this chunk is free. */
struct malloc_chunk* bk_nextsize;
};

typedef struct malloc_chunk* mchunkptr;

Daha önce belirtildiği gibi, bu parçaların da bazı meta verileri vardır, bu görüntüde çok iyi temsil edilmiştir:

Meta veri genellikle 0x08B olup, mevcut parça boyutunu belirtmek için son 3 biti kullanır:

  • A: 1 ise bir alt yığın, 0 ise ana arenadadır

  • M: 1 ise, bu parça mmap ile tahsis edilen bir alanın parçasıdır ve bir yığın parçası değildir

  • P: 1 ise, önceki parça kullanımdadır

Sonra, kullanıcı verileri için alan ve nihayet 0x08B, parça mevcut olduğunda önceki parça boyutunu belirtmek için (veya tahsis edildiğinde kullanıcı verilerini depolamak için) kullanılır.

Ayrıca, mevcut olduğunda, kullanıcı verileri ayrıca bazı verileri içermek için kullanılır:

  • fd: Bir sonraki parçaya işaretçi

  • bk: Önceki parçaya işaretçi

  • fd_nextsize: Listede kendisinden daha küçük olan ilk parçaya işaretçi

  • bk_nextsize: Listede kendisinden daha büyük olan ilk parçaya işaretçi

Listeyi bu şekilde bağlamanın, her bir parçanın kaydedilmesi gereken bir diziye ihtiyaç duymayı önlediğine dikkat edin.

Parça İşaretçileri

Malloc kullanıldığında, yazılabilir içeriğe işaret eden bir işaretçi döndürülür (başlıkların hemen ardından), ancak parçaları yönetirken, başlıkların (meta verilerin) başlangıcına işaret eden bir işaretçiye ihtiyaç vardır. Bu dönüşümler için bu fonksiyonlar kullanılır:

// https://github.com/bminor/glibc/blob/master/malloc/malloc.c

/* Convert a chunk address to a user mem pointer without correcting the tag.  */
#define chunk2mem(p) ((void*)((char*)(p) + CHUNK_HDR_SZ))

/* Convert a user mem pointer to a chunk address and extract the right tag.  */
#define mem2chunk(mem) ((mchunkptr)tag_at (((char*)(mem) - CHUNK_HDR_SZ)))

/* The smallest possible chunk */
#define MIN_CHUNK_SIZE        (offsetof(struct malloc_chunk, fd_nextsize))

/* The smallest size we can malloc is an aligned minimal chunk */

#define MINSIZE  \
(unsigned long)(((MIN_CHUNK_SIZE+MALLOC_ALIGN_MASK) & ~MALLOC_ALIGN_MASK))

Hizalama & minimum boyut

Chunk'a işaretçi ve 0x0f 0 olmalıdır.

// From https://github.com/bminor/glibc/blob/a07e000e82cb71238259e674529c37c12dc7d423/sysdeps/generic/malloc-size.h#L61
#define MALLOC_ALIGN_MASK (MALLOC_ALIGNMENT - 1)

// https://github.com/bminor/glibc/blob/a07e000e82cb71238259e674529c37c12dc7d423/sysdeps/i386/malloc-alignment.h
#define MALLOC_ALIGNMENT 16


// https://github.com/bminor/glibc/blob/master/malloc/malloc.c
/* Check if m has acceptable alignment */
#define aligned_OK(m)  (((unsigned long)(m) & MALLOC_ALIGN_MASK) == 0)

#define misaligned_chunk(p) \
((uintptr_t)(MALLOC_ALIGNMENT == CHUNK_HDR_SZ ? (p) : chunk2mem (p)) \
& MALLOC_ALIGN_MASK)


/* pad request bytes into a usable size -- internal version */
/* Note: This must be a macro that evaluates to a compile time constant
if passed a literal constant.  */
#define request2size(req)                                         \
(((req) + SIZE_SZ + MALLOC_ALIGN_MASK < MINSIZE)  ?             \
MINSIZE :                                                      \
((req) + SIZE_SZ + MALLOC_ALIGN_MASK) & ~MALLOC_ALIGN_MASK)

/* Check if REQ overflows when padded and aligned and if the resulting
value is less than PTRDIFF_T.  Returns the requested size or
MINSIZE in case the value is less than MINSIZE, or 0 if any of the
previous checks fail.  */
static inline size_t
checked_request2size (size_t req) __nonnull (1)
{
if (__glibc_unlikely (req > PTRDIFF_MAX))
return 0;

/* When using tagged memory, we cannot share the end of the user
block with the header for the next chunk, so ensure that we
allocate blocks that are rounded up to the granule size.  Take
care not to overflow from close to MAX_SIZE_T to a small
number.  Ideally, this would be part of request2size(), but that
must be a macro that produces a compile time constant if passed
a constant literal.  */
if (__glibc_unlikely (mtag_enabled))
{
/* Ensure this is not evaluated if !mtag_enabled, see gcc PR 99551.  */
asm ("");

req = (req + (__MTAG_GRANULE_SIZE - 1)) &
~(size_t)(__MTAG_GRANULE_SIZE - 1);
}

return request2size (req);
}

Not edin ki, toplam gereken alanı hesaplamak için yalnızca SIZE_SZ 1 kez eklenir çünkü prev_size alanı veri depolamak için kullanılabilir, bu nedenle yalnızca başlangıç başlığı gereklidir.

Parça verilerini al ve meta verileri değiştir

Bu fonksiyonlar bir parçaya işaretçi alarak çalışır ve meta verileri kontrol etmek/ayarlamak için faydalıdır:

  • Parça bayraklarını kontrol et

// From https://github.com/bminor/glibc/blob/master/malloc/malloc.c


/* size field is or'ed with PREV_INUSE when previous adjacent chunk in use */
#define PREV_INUSE 0x1

/* extract inuse bit of previous chunk */
#define prev_inuse(p)       ((p)->mchunk_size & PREV_INUSE)


/* size field is or'ed with IS_MMAPPED if the chunk was obtained with mmap() */
#define IS_MMAPPED 0x2

/* check for mmap()'ed chunk */
#define chunk_is_mmapped(p) ((p)->mchunk_size & IS_MMAPPED)


/* size field is or'ed with NON_MAIN_ARENA if the chunk was obtained
from a non-main arena.  This is only set immediately before handing
the chunk to the user, if necessary.  */
#define NON_MAIN_ARENA 0x4

/* Check for chunk from main arena.  */
#define chunk_main_arena(p) (((p)->mchunk_size & NON_MAIN_ARENA) == 0)

/* Mark a chunk as not being on the main arena.  */
#define set_non_main_arena(p) ((p)->mchunk_size |= NON_MAIN_ARENA)
  • Diğer parçaların boyutları ve işaretçileri

/*
Bits to mask off when extracting size

Note: IS_MMAPPED is intentionally not masked off from size field in
macros for which mmapped chunks should never be seen. This should
cause helpful core dumps to occur if it is tried by accident by
people extending or adapting this malloc.
*/
#define SIZE_BITS (PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA)

/* Get size, ignoring use bits */
#define chunksize(p) (chunksize_nomask (p) & ~(SIZE_BITS))

/* Like chunksize, but do not mask SIZE_BITS.  */
#define chunksize_nomask(p)         ((p)->mchunk_size)

/* Ptr to next physical malloc_chunk. */
#define next_chunk(p) ((mchunkptr) (((char *) (p)) + chunksize (p)))

/* Size of the chunk below P.  Only valid if !prev_inuse (P).  */
#define prev_size(p) ((p)->mchunk_prev_size)

/* Set the size of the chunk below P.  Only valid if !prev_inuse (P).  */
#define set_prev_size(p, sz) ((p)->mchunk_prev_size = (sz))

/* Ptr to previous physical malloc_chunk.  Only valid if !prev_inuse (P).  */
#define prev_chunk(p) ((mchunkptr) (((char *) (p)) - prev_size (p)))

/* Treat space at ptr + offset as a chunk */
#define chunk_at_offset(p, s)  ((mchunkptr) (((char *) (p)) + (s)))
  • Insue bit

/* extract p's inuse bit */
#define inuse(p)							      \
((((mchunkptr) (((char *) (p)) + chunksize (p)))->mchunk_size) & PREV_INUSE)

/* set/clear chunk as being inuse without otherwise disturbing */
#define set_inuse(p)							      \
((mchunkptr) (((char *) (p)) + chunksize (p)))->mchunk_size |= PREV_INUSE

#define clear_inuse(p)							      \
((mchunkptr) (((char *) (p)) + chunksize (p)))->mchunk_size &= ~(PREV_INUSE)


/* check/set/clear inuse bits in known places */
#define inuse_bit_at_offset(p, s)					      \
(((mchunkptr) (((char *) (p)) + (s)))->mchunk_size & PREV_INUSE)

#define set_inuse_bit_at_offset(p, s)					      \
(((mchunkptr) (((char *) (p)) + (s)))->mchunk_size |= PREV_INUSE)

#define clear_inuse_bit_at_offset(p, s)					      \
(((mchunkptr) (((char *) (p)) + (s)))->mchunk_size &= ~(PREV_INUSE))
  • Başlık ve altbilgi ayarlayın (parça numaraları kullanıldığında)

/* Set size at head, without disturbing its use bit */
#define set_head_size(p, s)  ((p)->mchunk_size = (((p)->mchunk_size & SIZE_BITS) | (s)))

/* Set size/use field */
#define set_head(p, s)       ((p)->mchunk_size = (s))

/* Set size at footer (only when chunk is not in use) */
#define set_foot(p, s)       (((mchunkptr) ((char *) (p) + (s)))->mchunk_prev_size = (s))
  • Parçanın içindeki gerçek kullanılabilir verinin boyutunu alın

#pragma GCC poison mchunk_size
#pragma GCC poison mchunk_prev_size

/* This is the size of the real usable data in the chunk.  Not valid for
dumped heap chunks.  */
#define memsize(p)                                                    \
(__MTAG_GRANULE_SIZE > SIZE_SZ && __glibc_unlikely (mtag_enabled) ? \
chunksize (p) - CHUNK_HDR_SZ :                                    \
chunksize (p) - CHUNK_HDR_SZ + (chunk_is_mmapped (p) ? 0 : SIZE_SZ))

/* If memory tagging is enabled the layout changes to accommodate the granule
size, this is wasteful for small allocations so not done by default.
Both the chunk header and user data has to be granule aligned.  */
_Static_assert (__MTAG_GRANULE_SIZE <= CHUNK_HDR_SZ,
"memory tagging is not supported with large granule.");

static __always_inline void *
tag_new_usable (void *ptr)
{
if (__glibc_unlikely (mtag_enabled) && ptr)
{
mchunkptr cp = mem2chunk(ptr);
ptr = __libc_mtag_tag_region (__libc_mtag_new_tag (ptr), memsize (cp));
}
return ptr;
}

Örnekler

Hızlı Yığın Örneği

Hızlı yığın örneği https://guyinatuxedo.github.io/25-heap/index.html adresinden ama arm64'te:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void main(void)
{
char *ptr;
ptr = malloc(0x10);
strcpy(ptr, "panda");
}

Ana fonksiyonun sonunda bir kesme noktası ayarlayın ve bilgilerin nerede saklandığını bulalım:

Panda dizesinin 0xaaaaaaac12a0 adresinde saklandığını görebiliyoruz (bu, x0 içindeki malloc tarafından verilen yanıttı). 0x10 byte öncesini kontrol ettiğimizde, 0x0 değerinin önceki parçanın kullanılmadığını (uzunluk 0) temsil ettiğini ve bu parçanın uzunluğunun 0x21 olduğunu görebiliyoruz.

Rezerve edilen ekstra alan (0x21-0x10=0x11), eklenen başlıklardan (0x10) gelmektedir ve 0x1, 0x21B olarak rezerve edildiği anlamına gelmez, ancak mevcut başlığın uzunluğunun son 3 biti bazı özel anlamlara sahiptir. Uzunluk her zaman 16-byte hizalı olduğundan (64 bit makinelerde), bu bitler aslında uzunluk numarası tarafından asla kullanılmayacaktır.

0x1:     Previous in Use     - Specifies that the chunk before it in memory is in use
0x2:     Is MMAPPED          - Specifies that the chunk was obtained with mmap()
0x4:     Non Main Arena      - Specifies that the chunk was obtained from outside of the main arena

Çoklu İş Parçacığı Örneği

Çoklu İş Parçacığı

```c #include #include #include #include #include

void* threadFuncMalloc(void* arg) { printf("Hello from thread 1\n"); char* addr = (char*) malloc(1000); printf("After malloc and before free in thread 1\n"); free(addr); printf("After free in thread 1\n"); }

void* threadFuncNoMalloc(void* arg) { printf("Hello from thread 2\n"); }

int main() { pthread_t t1; void* s; int ret; char* addr;

printf("Before creating thread 1\n"); getchar(); ret = pthread_create(&t1, NULL, threadFuncMalloc, NULL); getchar();

printf("Before creating thread 2\n"); ret = pthread_create(&t1, NULL, threadFuncNoMalloc, NULL);

printf("Before exit\n"); getchar();

return 0; }

</details>

Önceki örneği hata ayıklarken, başlangıçta yalnızca 1 arena olduğunu görebiliriz:

<figure><img src="../../.gitbook/assets/image (1) (1) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>

Daha sonra, malloc'u çağıran ilk iş parçacığı çağrıldığında, yeni bir arena oluşturulur:

<figure><img src="../../.gitbook/assets/image (1) (1) (1) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>

Ve içinde bazı parçalar bulunabilir:

<figure><img src="../../.gitbook/assets/image (2) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>

## Bins & Bellek Tahsisleri/Serbest Bırakmaları

Bins'lerin ne olduğunu ve nasıl organize olduklarını ve belleğin nasıl tahsis edildiğini ve serbest bırakıldığını kontrol edin:

<div data-gb-custom-block data-tag="content-ref" data-url='bins-and-memory-allocations.md'>

[bins-and-memory-allocations.md](bins-and-memory-allocations.md)

</div>

## Heap Fonksiyonları Güvenlik Kontrolleri

Heap ile ilgili fonksiyonlar, eylemlerini gerçekleştirmeden önce heap'in bozulmadığından emin olmak için belirli kontroller yapacaktır:

<div data-gb-custom-block data-tag="content-ref" data-url='heap-memory-functions/heap-functions-security-checks.md'>

[heap-functions-security-checks.md](heap-memory-functions/heap-functions-security-checks.md)

</div>

## Referanslar

* [https://azeria-labs.com/heap-exploitation-part-1-understanding-the-glibc-heap-implementation/](https://azeria-labs.com/heap-exploitation-part-1-understanding-the-glibc-heap-implementation/)
* [https://azeria-labs.com/heap-exploitation-part-2-glibc-heap-free-bins/](https://azeria-labs.com/heap-exploitation-part-2-glibc-heap-free-bins/)

Last updated