관리 메뉴

개발자비행일지

Heap 구조, Chunk란? 본문

▶ 보안

Heap 구조, Chunk란?

Cyber0946 2021. 3. 10. 16:54

Heap에 대해서 Haep memory 공격등을 학습하다 보면 Chunk라는 개념이 등장한다. 

여기서 Chunk란  header와 data 영역으로 구성된다. 

- malloc()으로 할당 받는 영역과 header를 포함한 영역을 뜻한다.

- header란 prev_size와 size를 뜻한다.

- 32bit에서는 8byte의 배수, 64bit에선 16byte의 배수로 할당이 된다.

- 64bit에서 malloc(1)을 하게되면 Data영역은 총 16만큼 할당이 된다는 의미다.

32비트 운영체제 Chunck

 

64비트 운영체제 Chunck

 

prev_size

- 이전 청크의 크기이다.

- 위 그림에서 2번 청크를 기준으로 이전 청크는 1번 청크이며, 1번 청크의 플래그를 제외한 크기이다.

- Data의 크기가 128비트 이상인 청크가 free될 때 다음 청크의 prev_size가 세팅이 된다. (64bit 기준)

- 즉 fastbin을 free할 땐 항상 0으로 유지되고 PREV_INUSE 비트가 0이 되어야만 세팅이 된다.

size

- 현재 청크의 크기이다.

- 하위 3bit는 flag로 쓰이는데, PREV_INUSE가 제일 중요하다.

--> PREV_INUSE(0x1): 이전 chunk가 사용 중 또는 fastbin일 때 설정되는 플래그 (★)

--> IS_MMAPPED(0x2): mmap() 함수로 할당된 chunk일 때 설정되는 플래그

--> NON_MAIN_ARENA(0x4): 멀티 쓰레드 환경에서 main이 아닐 때 생성되는 플래그

하위 3bit를 flag로 써도 되는 이유에 대해 잠깐 설명하고 넘어가겠다.

힙 영역은 무조건 32bit에선 8byte 단위, 64bit에선 16byte 단위로 할당된다.

이때 8과 16의 배수를 2진수로 변경했을 때 하위 3bit(1, 2, 4를 표현하는 수)는 사용하지 않는다.

1000 = 8

10000 = 16

11000 = 24

100000 = 32

즉 하위 3bit가 남기 때문에 플래그로 사용해도 되는 것이고 PREV_INUSE는 매우 중요하다!

PREV_INUSE의 사전적인 의미는 이전 청크가 현재 해제되지 않고 사용 중인지를 판단하는 플래그이고, 실질적으로 내포하고 있는 의미는 이전 청크는 병합의 후보로 간주돼선 안된다이다. 병합은 다음에 설명을 할텐데, fastbin은 병합과정을 거치지 않기때문에 이전 청크가 fastbin이라면 항상 세팅되어 있다.

48만큼의 크기를 할당 했을 때의 힙 모습은 다음과 같다. (64bit 기준)

prev_size는 당연히 0이다. 이전 청크는 존재하지 않기 때문이다. size는 0x41인데, 10진수로 변경해보면 65이다. 헤더 16과 데이터 48을 더한 크기이고 PREV_INUSE가 세팅이 되어있다. 첫 번째로 생성한 청크기 때문에 이전 청크가 존재하지 않는데 1로 세팅된 이유는 병합할 필요가 없기 때문에 설정된 것이다. 그리고 마지막에 20fc1 이란 값이 보이는데 이것은 Top Chunk라는 것인데 다음에 정리하겠다.

  • Chunk의 종류
  • 1. Allocated Chunk
  • 2. Freed Chunk
  • 3. Top Chunk

Allocated Chunk

- 사용중인 청크를 의미한다.

- prevsize, size, data로 구성된다.

Freed Chunk

- 해제된 청크를 의미한다.

- Allocated Chunk와 헤더 부분은 동일하지만 Data 부분에 FD, BK 등이 들어간다.

- FD는 다음 청크를 가리키는 포인터이다.

- BK는 이전 청크를 가리키는 포인터이다.

Top Chunk

- 힙 영역의 마지막에 위치하며 아직 할당되지 않은 영역이다.

- 재사용 가능한 chunk가 없을 때 할당 요청이 오면 Top chunk에서 분리해서 영역을 반환해준다.

- Top chunk와 인접한 chunk가 free되면 병합을 한다.

- 일반적으로 Top chunk의 크기는 0x21000이고, Top Chunk의 크기보다 큰 할당은 불가능하다.

재사용 가능한 chunk의 의미를 풀어서 설명하면 동일한 크기의 chunk가 free되어있을 때 Top Chunk로부터 영역을 받는 것이 아닌 해제되어 있는 영역을 할당해주는 것이다.

malloc(48)이 실행되었을 때의 Top Chunk의 변화는 다음과 같다.

Top Chunk의 size 부분의 마지막 비트도 마찬가지로 PREV_INUSE이다.

처음엔 0x21001이었다가 크기가 48인 요청이 들어오면 헤더 값을 포함한 64를 빼서 0x20fc1이 된다.

 

'▶ 보안' 카테고리의 다른 글

RTDs(Resistance Temperature Devices)  (0) 2022.12.23
Seebeck effect  (0) 2022.12.23
Independent Link Padding  (0) 2020.11.30
배너 그래빙(Banner Grabbing)  (0) 2020.11.30
리눅스 find 사용법  (0) 2020.07.13