Index
bins
Bin์ด๋ผ๋ ๊ตฌ์กฐ๋ฅผ ์ด์ฉํ์ฌ ํด์ ๋ ์ฒญํฌ๋ฅผ ํฌ๊ธฐ ๋จ์๋ก ๊ด๋ฆฌํ๋ค. ์ด๋ ๋ฉ๋ชจ๋ฆฌ ํ ๋น ์์ฒญ์ ์ด์ ์ ์ฌ์ฉํ๋ ํฌ๊ธฐ์ chunk๊ฐ ์๋ค๋ฉด ์ ์ํ๊ฒ ์ฌํ ๋นํ๊ธฐ ์ํจ์ด๋ค. ํฌ๊ธฐ์ ๋ฐ๋ผ 4๊ฐ์ง ์ ํ์ผ๋ก ๋๋๋ค(glibc-2.26 ์ดํ tcachebins๊ฐ ์ถ๊ฐ๋์ด 5๊ฐ์ง์ bins). ํฌ๊ธฐ๊ฐ ํด ์๋ก ํ ๋น/ํด์ ๊ฐ ๋๋ ค์ง๊ณ , ํฌ๊ธฐ๊ฐ ์์ ์๋ก ํ ๋น/ํด์ ๊ฐ ๋น ๋ฅธ bins๋ฅผ ์ฌ์ฉํ๋ค.
fast bin
์ด๋ฆ ๊ทธ๋๋ก ๋ฉ๋ชจ๋ฆฌ ํ ๋น๊ณผ ํด์ ๊ฐ ๊ฐ์ฅ ๋น ๋ฅธ bin์ด๋ค. LIFO(ํ์ ์ ์ถ) ๋ฐฉ์์ ์ฌ์ฉํ๊ณ , Freed chunk๊ตฌ์กฐ์์ fd์ ๊ฐ์ ์ด์ฉํด์ ๋จ์ผ ์ฐ๊ฒฐ๋ฆฌ์คํธ๋ก chunk๋ฅผ ๊ด๋ฆฌํ๋ค. ์์ ์ฝ๋๋ฅผ ํตํด์ chunk์ ํ ๋น๊ณผ ํด์ ์ ์ด๋ป๊ฒ ๊ด๋ฆฌํ๋์ง ํ์ธํด๋ณด์.
//Name : fastbin.c
//Compiler : gcc -o fastbin fastbin.c -no-pie -fno-stack-protector
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main(){
char *chunk0 = (char *)malloc(0x0);
char *chunk1 = (char *)malloc(0x10);
char *chunk2 = (char *)malloc(0x20);
char *chunk3 = (char *)malloc(0x25);
char *chunk4 = (char *)malloc(0x30);
char *chunk5 = (char *)malloc(0x80);
char *chunk6 = (char *)malloc(0x88);
char *chunk7 = (char *)malloc(0x90);
free(chunk0);
free(chunk1);
free(chunk2);
strcpy(chunk3, "1234567890123456789012345678901234567");
free(chunk3);
free(chunk4);
free(chunk5);
free(chunk6);
free(chunk7);
return 0;
}
fastbin์ด ๊ด๋ฆฌํ๋ chunk์ ํฌ๊ธฐ๋ 32bit ์ด์์ฒด์ ์์๋ 16~88byte(10๊ฐ์ bin)์ด๊ณ , 64bit ์ด์์ฒด์ ์์๋ 32~128byte(7๊ฐ์ bin๋ง ์ฌ์ฉ)์ด๋ค. 64bit ๊ธฐ์ค์ผ๋ก fastbin์ ์ํ๋ ์ฌ๋ฌ ์ฌ์ด์ฆ์ ์ฒญํฌ๋ฅผ ํ ๋นํ๊ณ ํด์ ํ๋ฉด์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ํ์ธํด๋ณด์.
์ ๋ฉ๋ชจ๋ฆฌ ์ํ๋ ์์ ์ฝ๋์ ๋ชจ๋ chunk๋ฅผ ํ ๋นํ๊ณ , ์์ง ํด์ (free)๊ฐ ์งํ๋์ง ์์ ์ํ์ด๋ค.
free(chunk0);
malloc(0)์ด ํ ๋น๋ chunk0์ด ํด์ ๋์๋ค. malloc ์ธ์๋ก 0์ ์คฌ์ง๋ง, ํด์ ๋์์ ๋์ chunk์ ๊ธฐ๋ณธ๊ตฌ์กฐ๋ฅผ ๋ํ๋ด๊ธฐ ์ํด์ 0x20์ size๋ฅผ ๊ฐ์ง๋ค. 0x20ํฌ๊ธฐ์ chunk๋ฅผ ๊ด๋ฆฌํ๋ fastbin[0]์ ๋ค์ด๊ฐ ๊ฒ์ ํ์ธํ ์ ์๋ค.
free(chunk1);
chunk1์ malloc(0x10)์ด์๋ค. ํ์ง๋ง chunk์ ์ค์ ํฌ๊ธฐ๋ data๋ฅผ ๋ด๋ ์์ญ(0x10)๊ณผ ํค๋(0x10)๊ฐ ํฉ์ณ์ ธ์ 0x20ํฌ๊ธฐ๊ฐ ๊ตฌ์ฑ๋๋ค. ๊ธฐ๋ณธ ๊ตฌ์ฑ์ ๊ฐ์ถ๊ธฐ ์ํด 0x20 ํฌ๊ธฐ๋งํผ ํ ๋น๋ chunk0๊ณผ ๊ฐ์ ํฌ๊ธฐ๋ฅผ ํ ๋น๋ฐ๊ฒ ๋๊ณ , ํด์ ์์ 0x20 ํฌ๊ธฐ๋ฅผ ๋ด๋ fastbin[0]์ ๋ค์ด๊ฐ๋ค. ์ด๋ fastbin์ LIFO(ํ์ ์ ์ถ) ๊ตฌ์กฐ๋ฅผ ๊ฐ์ง๊ธฐ ๋๋ฌธ์ ๋์ค์ ๋ค์ด๊ฐ chunk1(d49020)์ด ์ฌํ ๋น ํ์ ์ ๋จผ์ ํ ๋น๋๋ค. ์ ์ฌ์ง์์๋ chunk1(d49020)์ fd ๊ฐ์ chunk0(0xd49000)์ผ๋ก fd๋ฅผ ํตํด ์ฐ๊ฒฐ๋์ด ๊ด๋ฆฌํ๋ ๊ฒ์ ํ์ธํ ์ ์๋ค.
free(chunk2);
chunk2๋ malloc(0x20)์ด๋ค. ํค๋ ํฌ๊ธฐ 0x10์ ๋ํ์ฌ 0x30์ ํฌ๊ธฐ๋ฅผ ๊ฐ์ง๊ณ , ํด์ ์ fastbin[1]์ ๋ค์ด๊ฐ ๊ฒ์ ํ์ธํ ์ ์๋ค. ์์ ์ค๋ช ํ ๋ด์ฉ๊ณผ ์ค๋ณต๋๋ ์ค๋ช ์ ์๋ตํ๋ค.
strcpy(chunk3, "1234567890123456789012345678901234567");
chunk3์ malloc(0x25)์ผ๋ก, ํค๋ ๊ฐ๊น์ง 0x35 ํฌ๊ธฐ์ ๊ณต๊ฐ์ด ํ์ํ๋ค. ์ด๋, chunk๋ 16byte ์ ๋ ฌ๋ ํฌ๊ธฐ๋ก ํ ๋น๋๋ค. ๊ทธ๋ฌ๋ฉด 0x30์ผ๋ก ๋ด์ ์ ์์ผ๋, 0x40์ ํฌ๊ธฐ๋ฅผ ํ ๋นํ ๊ฒ์ด๋ผ๊ณ ์๊ฐํ ์ ์๋ค. ํ์ง๋ง ์ ์ฌ์ง์์ size๊ฐ 0x30์ธ ๊ฒ์ ํ์ธํ ์ ์๋ค.
์ ๋ณ๋ก ๋ค๋ฅธ chunk์ด๋ค. ์๋ chunk์ prev_size ํ๋๊ฐ ๋ฎ์ฌ ๋ฐ์ดํฐ๋ฅผ ๋ด๊ณ ์๋ค. allocated chunk์ธ ๊ฒฝ์ฐ, ์ธ์ ํ ๋ค chunk์์ prev_size ๋ถ๋ถ๊น์ง ๋ฐ์ดํฐ๋ฅผ ๋ด์ ์ฌ์ฉํ๋ค.
free(chunk3);
chunk3 ํด์ ์, 0x30 ํฌ๊ธฐ์ธ chunk๋ฅผ ๋ด๋ fastbin[1]์ผ๋ก ์ ๋ค์ด๊ฐ๋ค.
free(chunk4);
chunk4๋ malloc(0x30)์ด๋ค. ์ ์์ ์ผ๋ก ์ free๋์๋ค.
free(chunk5);
chunk5๋ malloc(0x80)์ ํ๋ค. ํค๋ ์ ๋ณด์ ํฌ๊ธฐ์ธ 0x10์ ๋ํ๋ฉด 0x90์ ํฌ๊ธฐ๋ฅผ ๊ฐ์ง๋ค. 0x90์ 144byte์ด๊ณ , 64bit ๊ธฐ์ค์ผ๋ก 32~128byte๋ฅผ fastbin์ผ๋ก ๊ด๋ฆฌํ๋ค๊ณ ํ์ผ๋ฏ๋ก, fastbin์ ๋ค์ด๊ฐ์ง ์๋๋ค. heapinfo ์ size๊ฐ 0์ด์๋ unsorted bin์ด 0x90์ผ๋ก ๋ฐ๋ ๊ฒ์ ํ์ธํ ์ ์๊ณ , ํด์ ๋ chunk์ ์ฃผ์ ๊ฐ์ด ์จ์ ธ ์๋ค. ๋ํ parseheap์ผ๋ก ํด๋น ์ฒญํฌ์ fd์ bk๊ฐ ์ด๋ ํ ํน์ ์ฃผ์ ๊ฐ์ผ๋ก ๋์ผํ๊ฒ ๋ค์ด๊ฐ ๊ฒ๋ ๋ณผ ์ ์๋ค.
free(chunk6);
chunk6์ malloc(0x88)๋ก ํ ๋นํ์๊ณ , chunk์ ํฌ๊ธฐ๋ 0x90์ด๋ค. ์ด ๋ํ freeํ์ ๋, fastbin์ ๋ค์ด๊ฐ ํฌ๊ธฐ๊ฐ ์๋๋ฉฐ, unsorted bin์ size๊ฐ ์ฆ๊ฐํ ๊ฒ์ ๋ณผ ์ ์๋ค. ์ด๋ chunk์ chunk๊ฐ ์ธ์ ํ๊ธฐ ๋๋ฌธ์ ๋ณํฉ๊ณผ์ ์ด ์ผ์ด๋ ๊ฒ์ด๋ค. ๊ทธ์ ๋ฐํด fastbin์ ์ธ์ ํ chunk๋ผ๊ณ ํ๋๋ผ๋, ์์ ๋ณธ ๊ฒ ์ฒ๋ผ ๋ณํฉ๊ณผ์ ์ด ์ผ์ด๋์ง ์๋๋ค.
free(chunk7);
๋ชจ๋ chunk๊ฐ free๋์๋ค. ๋ง์ง๋ง free์ฌ์ ์ธ๊ฐ(?)
unsorted bin
์์ fastbin์ ๋ณด๋ฉด์ ๋ง์ง๋ง์ ์ด์ง ํ์ธํ๋ bin์ด๋ค. fastbin๊ณผ๋ ๋ค๋ฅด๊ฒ FIFO(์ ์ ์ ์ถ) ๋ฐฉ์์ ์ฌ์ฉํ๊ณ 1๊ฐ์ bin๋ง์ ์ฌ์ฉํ๋ค. Freed chunk๊ตฌ์กฐ์์ fd์ bk๋ฅผ ์ฌ์ฉํ์ฌ ์ด์ค ์ฐ๊ฒฐ๋ฆฌ์คํธ๋ก ๊ด๋ฆฌํ๋ค.
unsorted bin์ fastbin์ ๋ค์ด๊ฐ์ง ์๋ chunk๊ฐ small bin๊ณผ large bin์ ๋ค์ด๊ฐ๊ธฐ ์ , ํ ๋น๊ณผ ํด์ ์ ์๋๋ฅผ ๋์ด๊ธฐ ์ํด chunk๋ฅผ unsorted bin์ ์ ์ ์ ์ฅํ๋ค. chunk๋ฅผ ํ ๋นํ ๋ fastbin์ ๋ง๋ ํฌ๊ธฐ๊ฐ ์๋ค๋ฉด, unsorted bin์ ํ์ธํ์ฌ ์ฌํ ๋น๋๊ฑฐ๋ ์๋์ bin์ผ๋ก ๋์๊ฐ๋ค. unsorted bin์ ๋ค์ด๊ฐ chunk๋ NON_MAIN_ARENA ํ๋๊ทธ๊ฐ true๊ฐ ๋์ง ์๋๋ค.
unsorted bin์ผ๋ก free๋๋ ๊ณผ์ ์ ์์ ์ฝ๋๋ก ํ์ธํด๋ณด์.
//Name : unsortedbin.c
//Compiler : gcc -o unsortedbin unsortedbin.c -no-pie -fno-stack-protector
#include <stdio.h>
#include <stdlib.h>
int main()
{
char* chunk1 = malloc(0x80);
char* chunk2 = malloc(0x10);
char* chunk3 = malloc(0x80);
char* chunk4 = malloc(0x10);
char* chunk5 = malloc(0x80);
char* chunk6 = malloc(0x10);
free(chunk1);
free(chunk3);
free(chunk5);
char* chunk7 = malloc(0x500);
free(chunk7);
return 0;
}
์ ์ฌ์ง์ ์์ ์ฝ๋์์ ๋ชจ๋ chunk๊ฐ ํ ๋น๋ ์ํ์ ๋ฉ๋ชจ๋ฆฌ ๊ตฌ์กฐ์ด๋ค. ๋จผ์ , unsorted bin์ผ๋ก ๋ฃ์ chunk๋ fastbin์ ํฌ๊ธฐ ๋ฒ์๋ณด๋ค ํฐ 0x90์ผ๋ก ํ ๋นํด์คฌ๊ณ , ์ด 0x90 ํฌ๊ธฐ์ chunk๋ค์ด ์ฐ์์ ์ผ๋ก ์ธ์ ํด์์ผ๋ฉด ํด์ ๊ณผ์ ์์ ๋ณํฉ์ด ์ด๋ค์ง๊ธฐ ๋๋ฌธ์ ์ค๊ฐ์ค๊ฐ fastbin ํฌ๊ธฐ์ chunk๋ฅผ ํ ๋นํด์คฌ๋ค.
free(chunk1);
chunk1์ ํด์ ๊ฐ ์ด๋ค์ง๋ฉด unsorted bin์ผ๋ก chunk๊ฐ ๋ค์ด๊ฐ๋ค. ์ด๋, ํด์ ๋ ์ฒญํฌ๋ ์ด์ค ์ฐ๊ฒฐ๋ฆฌ์คํธ๋ก ๊ด๋ฆฌ๊ฐ ๋๋ค. fd์ bk๋ฅผ ๋ณด๋ฉด ์ฃผ์ ๊ฐ์ด ๋ค์ด๊ฐ ์๋ค. ์ด ๊ฐ์ ํ์ธํด๋ณด๋ฉด main_arena+88 ์์น์ ์ฃผ์์ธ ๊ฒ์ ์ ์ ์๋ค. ๋ง์ฝ ์ด ์ฃผ์๋ฅผ leak ํ ์ ์๋ค๋ฉด, ์ด๋ฅผ ํตํด libc base๋ฅผ ๊ตฌํ ์ ์๋ค.
free(chunk3);
chunk3์ด ํด์ ๋๋ฉด, ์ญ์ unsorted bin์ ์ฐ์ ์ ์ผ๋ก ๋ค์ด๊ฐ๋ค. main_arena+88์ ๊ธฐ์ค์ผ๋ก fd์ bk๋ก chunk๊ฐ ์ฐ๊ฒฐ๋์ด ์๋ ๊ฒ์ ํ์ธํ ์ ์๋ค. ๋ง์ฝ ์ฌ๊ธฐ์ ์ฌํ ๋น์ด ์ด๋ฃจ์ด์ง๋ฉด, ๋จผ์ ๋ค์ด์๋ 0xa7d000์ด ํ ๋น๋๊ฒ ๋ ๊ฒ์ด๋ค.
free(chunk5);
chunk5๊ฐ ํด์ ๋ ๋ฉ๋ชจ๋ฆฌ ๊ตฌ์กฐ์ด๋ค. ์์ ์ค๋ช ๊ณผ ๊ฐ์ด unsorted bin์ ์ ๋ค์ด๊ฐ๋ค. ํ์ฌ๊น์ง์ bins ์ํ์์ ์ฌํ ๋น์ ํ๋ฉด์ bins์ ๋ณํ๋ฅผ ์ดํด๋ณด์.
char* chunk7 = malloc(0x500);
chunk7์ malloc(0x500)์ ํด์คฌ๋ค. ํ ๋น ์ ์ ์ผ ๋จผ์ fast bin ํฌ๊ธฐ๊ฐ ์๋๊ธฐ ๋๋ฌธ์ unsorted bin์์ ์๋ง๋ chunk๋ฅผ ํ์ธํ ๊ฒ์ด๋ค. ํ์ง๋ง unsorted bin์ chunk๋ค์ ํฌ๊ธฐ๋ 0x90์ด์์ผ๋ฏ๋ก, malloc(0x500)์ ์ ํฉํ์ง ์๋ค. ์ฌํ ๋น ๊ณผ์ ์ด unsorted bin์์ ์ด๋ค์ง์ง ์์๊ธฐ ๋๋ฌธ์ ํด๋น chunk๋ค์ ํฌ๊ธฐ์ ๋ง๋ small bin์ผ๋ก ์ฎ๊ธด๋ค.
free(chunk7);
๋ค์ 0x500 ํฌ๊ธฐ์ chunk7์ ํด์ ํด์ฃผ๋ฉด, unsorted bin์ ๋ค์ด๊ฐ์ง ์์๋ค. ์ด ๊ณผ์ ์ top chunk์ ๋ฐ๋ก ์ธ์ ํ๊ธฐ ๋๋ฌธ์ ๋ณํฉ๊ณผ์ ์ด ์ด๋ค์ง ๊ฒ์ด๋ค. ๋ง์ฝ ๊ทธ ์๋ ๋ค๋ฅธ chunk๊ฐ ์กด์ฌํ๋ค๋ฉด, unsorted bin์ ๋ค์ด๊ฐ์ ๊ฒ์ด๋ค.
๋ค์ ์์ ์ฝ๋๋ก small bin๊ณผ large bin, ๊ทธ๋ฆฌ๊ณ last_remainder์ ๋ํด ์์๋ณด์.
//Name : bins.c
//Compiler : gcc -o bins bins.c -no-pie -fno-stack-protector
#include <stdio.h>
#include <stdlib.h>
void main()
{
char* chunk1 = malloc(1000);
char* chunk2 = malloc(0x10);
char* chunk3 = malloc(1024);
char* chunk4 = malloc(0x10);
free(chunk1);
free(chunk3);
char* chunk5 = malloc(1200);
char* chunk6 = malloc(0x10);
free(chunk5);
}
small bin
์์ unsorted bin์์ ์ฌํ ๋น๋์ง ๋ชปํ ๊ฒฝ์ฐ, chunk์ ํฌ๊ธฐ๊ฐ fast bin๋ณด๋ค ํฌ๊ณ 512byte(64bit ์ด์์ฒด์ ์ธ ๊ฒฝ์ฐ 1024byte) ๋ณด๋ค ๋ฏธ๋ง์ธ ๊ฒฝ์ฐ์ small bin์ผ๋ก ๊ด๋ฆฌํ๊ฒ ๋๋ค. ์ด bin ๋ํ FIFO(์ ์ ์ ์ถ) ๋ฐฉ์์ด๊ณ , ํฌ๊ธฐ์ ๋ฐ๋ผ 62๊ฐ์ bin์ ๊ฐ์ง๋ค.
chunk4๊น์ง ํ ๋น๋๊ณ chunk1๊ณผ chunk3์ freeํ ์ํ์ด๋ค. ์ด ์ํ์์ 1200byte ํฌ๊ธฐ๋ก malloc์ ํด์ฃผ๋ฉด, unsorted bin์์ ํด๋นํ๋ ํฌ๊ธฐ์ chunk๊ฐ ์์ผ๋ฏ๋ก, unsorted bin ์์ ๋๊ฐ์ chunk๋ ๊ฐ์ ํฌ๊ธฐ์ ํด๋นํ๋ bin์ ๋ค์ด๊ฐ ๊ฒ์ด๋ค.
์ด๋ smallbin์ ๋ค์ด๊ฐ chunk๋ฅผ ํ์ธํด๋ณด์.
์ญ์๋ fd์ bk๋ฅผ ์ด์ฉํด์ chunk๋ฅผ ๊ด๋ฆฌํ๊ณ , ํฌ๊ธฐ์ ๋ฐ๋ผ main_arena๋ฅผ ๊ธฐ์ค์ผ๋ก ๊ด๋ฆฌํ๋ค.
large bin
์์ ์ค๋ช ํ๋ small bin๊ณผ ๊ฐ์ด FIFO(์ ์ ์ ์ถ) ๋ฐฉ์์ด๋ฉฐ, 63๊ฐ์ bin์ ๊ฐ์ง๋ค. 512byte(64bit ์ด์์ฒด์ ์ธ ๊ฒฝ์ฐ 1024byte) ๋ณด๋ค ํฐ chunk๋ฅผ ๊ด๋ฆฌํ๋ค.
small bin์ ์๋ ์ฌ์ง๊ณผ ๋์ผํ๋ค. ์ด๋ largebin์ ๋ค์ด๊ฐ chunk๋ฅผ ํ์ธํด๋ณด์.
fd์ bk๋ฅผ ์ด์ฉํด์ chunk๋ฅผ ๊ด๋ฆฌํ๋ค. ํ์ง๋ง, ๊ทธ ์๋ fd_nextsize์ bk_nextsize์ ํ๋ ๊ฐ์ด ๋ค์ด๊ฐ ๊ฒ์ ํ์ธํ ์ ์๋ค. ํ์ฌ์ chunk ํฌ๊ธฐ๋ณด๋ค ์์ chunk๋ฅผ fd_nextsize, ํฐ chunk๋ฅผ bk_nextsize๋ก ์ค์ ํ์ฌ chunk๋ฅผ ๊ด๋ฆฌํ๋ค. ํ์ฌ๋ ํ๋์ chunk๊ฐ ์กด์ฌํ๊ธฐ ๋๋ฌธ์ ๋ ํ๋์ ๊ฐ์ด ๊ฐ๋ค.
last_remainder
chunk6์ ํ ๋น์ด ์ด๋ค์ง ์ํ์ ๋ฉ๋ชจ๋ฆฌ ๊ตฌ์กฐ์ด๋ค.
fast bin ํฌ๊ธฐ์ด๊ณ , small bin์ ์๋ chunk๋ฅผ ๋ถ๋ฆฌํ์ฌ 0x18a3000 ์ฃผ์๋ฅผ ๊ฐ์ง๋ ๊ฒ์ ๋ณผ ์ ์๋ค. ์ด๋ fast bin ๋งํผ ํฌ๊ธฐ๋ฅผ ํ ๋นํด์ฃผ๊ณ , top chunk์๋ ์ธ์ ํ์ง ์์ ๋ณํฉ๋์ง ์๋๋ค. ์ด๋ฌํ chunk๋ฅผ last_remainder chunk๋ผ๊ณ ํ๋ค.
์์ธํ ํ์ธํด๋ณด๋ฉด 0x20๋งํผ fastbin์ผ๋ก ๋ถ๋ฆฌํ๊ณ , 0x18a3020๋ถํฐ ๋ค์ chunk๋ฅผ ๊ตฌ์ฑํ๋ค. ์ด๋ ์ ์ฒญํฌ๊ฐ ์ฌ์ฉ์ค์ด๋ฏ๋ก, sizeํ๋์ PREV_INUSE ํ๋๊ทธ๊ฐ true๊ฐ ๋๋ค.
tcache bin
Uploaded by N2T