우리가 malloc 등을 통해 메모리를 할당할 경우, 아래와 같은 청크가 하나 할당되는거랑 똑같습니다.
[이전의 청크 크기(할당된 경우)]
[현재 청크 크기][P]
[메모리 영역]
다음 청크..
만약 할당 해제를 시키면 청크는 어떻게 변할까요?
free()를 통해 할당을 해제시키면..
[이전 청크 크기]
[현재 청크 크기][P]
[다음 청크의 포인터]
[이전 청크의 포인터]
[미사용 영역]
다음 청크...
malloc.c에 정의되어있는 구조는 다음과 같습니다.
--malloc.c #malloc 자료구조
/*
Type declarations
*/
struct malloc_chunk
{
INTERNAL_SIZE_T prev_size; /* Size of previous chunk (if free). */
INTERNAL_SIZE_T size; /* Size in bytes, including overhead. */
struct malloc_chunk* fd; /* double links -- used only if free. */
struct malloc_chunk* bk;
};
...
이런식으로 다음 청크의 포인터(fd)와 이전 청크의 포인터(bk) 필드가 중간에 생성됩니다.
뭐 이런 청크들의 집합을 bin이라고 부릅니다(fastbin은 싱글, 나머지는 이중 링크드리스트 형식이라는데 fastbin은 나중에알아볼게여)
헌데 bins가 이렇게 더블 링크드 리스트 형식으로 연결되어 있는 이유가 뭘까용?
이후에 새로운 동적 메모리 할당 요청이 있을 경우 먼저 free된 chunk들의 리스트를 먼저 검색한 후, 재할당 함으로써 효율성을 높이기 위함입니다. 확실히 메모리를 효율적으로 사용할 수 있게 되겠지요. 아무튼 이러한 알고리즘을 bins management라고 부릅니다.
음..중요한건 free과정인데요. 이 free과정에서 이전에 free되어서 사용되지 않는 영역(이전이든, 이후든)을 찾아서 병합과정을 수행합니다.
이 과정을 수행하게 된다면 당연히 free과정에서 포인터가 계속 바뀌겠죠? 아무튼 free이후의 청크 영역을 다시한번 봅시다.
[이전 청크 크기]
[현재 청크 크기][P]
[다음 청크의 포인터]
[이전 청크의 포인터]
[미사용 영역]
다음 청크...
현재 청크 크기 바로 다음에 P라는 플래그가 하나 있죠? PREV_INUSE라는 플래그인데, 이전 청크가 사용 중인지 1과 0으로 구분하는 플래급니다
만약 이 플래그가 0이라면 이전 청크랑 병합하는 과정을 수행하게 되는거죠..
#define unlink(P, BK, FD)
{
BK = P->bk;
FD = P->fd;
FD->bk = BK;
BK->fd = FD;
}
이 병합과정을 해주는게 위 unlink 매크로라고 할 수 있습니다.
위와 같이 p의 bk와 fd를 각각 fd의 bk와 bk의 fb로 재설정해주는 부분을 확인할 수 있습니다..
문제는 이런식으로 포인터를 변경함으로써 임의의 주소 영역이 같이 병합되어 덮어씌어질 수 있다는 것입니다.
어떻게 공격에쓰일수 있는가..하면 좀있다가 protostar heap 풀이를 통해 다뤄볼게요!
http://www.hackerschool.org/HS_Boards/data/Lib_system/doublefree.txt
를 참고했습니다.
'공부' 카테고리의 다른 글
gdb x command (0) | 2015.11.09 |
---|---|
Une simple Exploitation de vulnérabilité Format String (0) | 2015.11.02 |
힙 (0) | 2015.10.26 |
dynamic linker (0) | 2015.10.18 |
vdso (0) | 2015.10.17 |