First Fit

Reading time: 5 minutes

tip

学习和实践 AWS 黑客技术:HackTricks Training AWS Red Team Expert (ARTE)
学习和实践 GCP 黑客技术:HackTricks Training GCP Red Team Expert (GRTE)

支持 HackTricks

First Fit

当你在程序中使用 glibc 释放内存时,会使用不同的“桶”来管理内存块。以下是两种常见场景的简化解释:未排序桶和快速桶。

Unsorted Bins

当你释放一个不是快速块的内存块时,它会进入未排序桶。这个桶就像一个列表,新释放的块被添加到前面(“头”)。当你请求一个新的内存块时,分配器从后面(“尾”)查看未排序桶,以找到一个足够大的块。如果未排序桶中的块大于你所需的大小,它会被拆分,前面的部分被返回,剩余的部分留在桶中。

示例:

  • 你分配 300 字节(a),然后 250 字节(b),释放 a 并再次请求 250 字节(c)。
  • 当你释放 a 时,它进入未排序桶。
  • 如果你再次请求 250 字节,分配器在尾部找到 a 并将其拆分,返回适合你请求的部分,并将其余部分保留在桶中。
  • c 将指向之前的 a 并填充 a 的内容。
c
char *a = malloc(300);
char *b = malloc(250);
free(a);
char *c = malloc(250);

Fastbins

Fastbins用于小内存块。与未排序的bins不同,fastbins将新块添加到头部,创建后进先出(LIFO)行为。如果您请求一个小内存块,分配器将从fastbin的头部提取。

示例:

  • 您分配四个20字节的块(abcd)。
  • 当您以任何顺序释放它们时,释放的块会被添加到fastbin的头部。
  • 如果您随后请求一个20字节的块,分配器将从fastbin的头部返回最近释放的块。
c
char *a = malloc(20);
char *b = malloc(20);
char *c = malloc(20);
char *d = malloc(20);
free(a);
free(b);
free(c);
free(d);
a = malloc(20);   // d
b = malloc(20);   // c
c = malloc(20);   // b
d = malloc(20);   // a

其他参考资料与示例