내용 보기

작성자

관리자 (IP : 172.17.0.1)

날짜

2020-11-18 06:50

제목

[메모리 구조] (stack, heap, buffer overflow)


프로그램을 만들고 실행을 하게되면 메모리 라는 곳에 코드들이 올라가 실행되게 됩니다.
사실 메모리는 물리적 메모리(Physical Memory)와 가상 메모리(Virtual Memory)로 나뉘게 됩니다.
일반적으로 코드를 실행하면 가상메모리에 적재 됩니다.

물리적 메모리는 RAM이고 가상 메모리는 HDD의 용량에서 가져와 사용하게 됩니다.
운영체제는 프로그램을 실행할 때 필요한 최소정보만 RAM에 저장을 합니다.
그리고 이를 Working set이라고 합니다.

그 후 프로그램을 실행하면서 필요한 데이터 정보를 가상 메모리에서 가져와
상황에 맞게 물리적 메모리에 맵핑하고 맵핑을 해제하고
이런 작업을 반복하게 됩니다. 이것을 페이징(Paging)기법 이라고 합니다.

가상메모리의
 주소 데이터들을 일정한 크기의 블록으로 쪼게 놓은걸 페이지(Page)라고 하며
물리메모리의 주소 데이터들을 일정한 크기의 블록으로 쪼게 놓은걸 프레임(Frame)라고 합니다.
그래서 같은 크기의 블록들을 메모리에 맵핑하며 프로그램이 동작하게 됩니다.
이렇게 블록 단위로 나눈 이유는 CPU의 부담을 덜어주기 위해서 입니다.
(너무 작은 데이터 단위면 작업이 빈번히 많이 일어나기 때문입니다.)

대충 그리자면 이런식??
그럼 이제 가상메모리에 적재되는 메모리구조에 대해 알아보겠습니다.


이런식으로 구성이 되어 있습니다.
그리고 저희가 봐야할 곳은 힙 영역과 스택 영역 입니다.
두개는 메모리 적재방법에 차이가 있습니다.


일반적인 변수들이 스택에 적재되면 큰 주소값을 시작으로 점차 주소 값이 작아지는걸 볼 수 있습니다.
반대로 힙은 처음 주소 값을 기준으로 점차 커지는걸 볼 수 있습니다.

이런식의 차이점을 두는 가장 큰 이유는 
버퍼오버플로우(Buffer OverFlow)를 막기 위해서 입니다.
스택 영역 뒤를 보시면 커널 영역이 있습니다. 

옛날, 변수에 스택 영역이 
초과되는 크기의 데이터를 저장한 후 커널 영역에 침범해 데이터를 조작하여 관리자 권한같은
해킹을 많이 했었습니다.
이런 사고를 막고자 스택 영역은 큰 주소 값을 시작으로 점차 아래로 주소 값이 할당되는 것입니다.
(※지금도 Buffer overFlow는 많이 사용되고 있습니다. 구글링만 해도 리눅스의 관리자 권한 취득하는 툴을 검색해 보시면
대부분 Buffer overFlow 기법으로 해킹되는 install툴이 많이 있는걸 알 수 있습니다.)

그리고 요즘 코드를 컴파일 하고 주소 값을 확인해보면 Window 10 64bit 기준
메모리에 int는 12바이트 double은 15바이트씩 넉넉한 메모리 할당이 되는걸 확인할 수 있었습니다.
(코드상 int는 4바이트 double은 8바이트지만 변수와 변수 사이의 공간은 int는 12바이트, double은 15바이트씩 차지하고 있습니다.)
매 실행마다 주소 값 또한 바뀌구요.
이는 Buffer OverFlow를 막기 위해서 라고 합니다. 정확하게는 원치 않은 데이터 침범을 막기 위함이라고 하는데
결국 같은 말이죠.

출처1

https://hwan-shell.tistory.com/13

출처2