원래는 처음부터 다뤘어야 하는 부분이지만, 내가 보는 책의 순서가 이러한 점도 있고 또 앞의 내용들과는 깊이 관련되지 않은
내용이기 때문에 지금 다루게 되었다.
특히 이번에 알아 볼 것은 가상 메모리의 구조이다.
가상메모리가 무엇인지 일단 알아야 하기 때문에 아래에 정의를 적어두었다.
[가상메모리 정의]
가상메모리란 물리적인 실체를 가지고 있지 않은 메모리를 말하며, OS가 만들어낸 논리적인 형태의 메모리를 뜻한다.
가상 메모리에 저장된 데이터라고 해서 가상으로 저장할 수는 없으며, 가상 메모리의 데이터는 물리메모리나 하드 드라이브에 저장된다. 가상 메모리는 VAS라는 것을 OS로부터 할당받는다.
* VAS(Virtual Address Space) : 가상 메모리에 할당되는 주소를 말하며 물리메모리의 주소와는 다른
주소이다.
32bit 시스템의 경우 4GB 크기의 가상 메모리 영역을 할당 받으며, 64bit 시스템의 경우 이론적으로 17EB의 가상 메모리 영역을
할당 받지만, 64bit의 경우 할당받는 영역의 크기가 너무 크고 비효율적이어 8TB정도로 제한을 하고 있다.
가상 메모리의 크기는 위의 설명에서 보았듯이 시스템의 bit에 따라 정해져있으며 프로세스의 크기에 따라 변하지 않고
무조건적으로 정해진 크기가 할당된다.
또한 프로세스는 자신에게 할당 된 가상메모리의 영역을 자신의 것으로만 생각하고 단편화 되지 않은 연속적인 주소의
공간으로 인식한다.
그렇기에 시스템에 상관없이 매번 고정된 크기의 가상 메모리를 할당 받아 프로세스는 시스템마다 다른 메모리 크기의
한계를 느끼지 않고 실행 될 수 있는 것이다.
32bit 시스템의 메모리 구조를 가식화 해보면 아래 그림과 같다.
간단하게 그려봤을 때 가상메모리는 위와 같은 형태를 지니고 있다.
좀 더 세부적으로 그린다면 아래와 같다.
위 그림을 보면 가상메모리의 커널영역은 여러가지의 것들이 들어가 있는 것을 볼 수 있는데 이 것들은 그림에서처럼
순차적으로 저장되어 있지 않고 여기저기 흩어져 있다.
편의상 그림을 이렇게 그린 것이다.
메모리 덤프를 하면 사용자영역에 있는 데이터들은 불완전한 형태로 덤프되는 경우가 있고 커널 영역은 온전한 형태로 덤프가
되는 경우가 있는데 이러한 경우는 가상메모리에서 사용자 영역에서 데이터가 물리메모리와 페이지 파일을 오고 가기 때문이다.
프로세스가 사용하는 데이터가 오랫동안 사용되지 않을 경우 페이지 파일에 저장해두고 필요할 경우 다시 물리적 메모리에
적재해 사용하는 방식때문에 불완전하게 덤프가 되는 것이다.
커널 영역의 경우 시스템에 필요한 데이터들이고 자주 사용되는 것들이기 때문에 페이지 파일에 저장하지 않고 물리메모리에
저장되기 때문에 온전하게 덤프가 되는 것이다.
가상메모리와 물리적 메모리의 주소는 맵핑이 되어 있는데 가상메모리의 어떤 데이터의 주소가 다른 프로세스의 가상메모리의
어떤 데이터 주소와 같다고 하더라도 물리적 메모리에서의 주소는 다르기 때문에 서로 충돌이 일어나거나 데이터를
덮어씌우지 않는다.
아래 그림은 두개의 서로 다른 프로세스가 똑같은 가상메모리 주소에 똑같은 데이터를 저장하였을 때 물리적 메모리에는
어떻게 저장되는가를 보여주는 그림이다.
위의 관계를 이해했다면 이제 가상메모리와 물리적메모리 간의 주소가 어떻게 변환되는지는 알아야 한다.
아래에 보기 편하도록 정리를 해두었다.
[가상메모리와 물리적메모리 사이의 주소 변환]
가상 메모리의 주소는 32bit 시스템에서는 32bit 길이를 갖는다. 가상 주소가 물리주소로 변환 될 때에는 2개의 테이블과 한개의 오프셋을 거쳐 변환되는데 이러한 변환 과정을 거치는 이유는 4GB 가상 메모리와 페이지 프레임 단위로 구성되어 있는 실제 메모리 사이의 맵핑 정보를 하나의 표로 만들게 되면 4MB정도가 되는 표가 만들어진다.
프로세스마다 이러한 표를 만들어 메모리에 적재하면 메모리 낭비이고, 안올리면 맵핑 속도가 크게 저하된다는 문제점이 생긴다. 이러한 이유로 윈도우는 가상메모리와 물리메모리 사이의 맵핑을 2개의 테이블로 나누고, 그 중 첫번째 테이블(페이지 디렉토리 테이블)만 메모리에 보관하고 나머지 하나의 테이블을 필요할 때만 메모리에 적재한다.
메모리는 페이지(page)라는 단위로 불리는 일정 크기의 단위를 사용하여 물리적메모리를 관리하는데 가상주소와 물리주소의 맵핑 또한 이 페이지를 기준으로 이루어진다.
[가상주소를 이용해 물리주소 찾기]
각각의 페이지는 첫번째 페이지부터 0번 순서가 매겨지며, 이 번호를 페이지 프레임 넘버(Page Frame Number)라고 한다.
가상주소의 구조는 다음과 같다.
이와 같은 정보를 이용하여 가상주소를 토대로 물리주소를 찾을 수 있다.
방법은 다음과 같다.
1. 페이지 디렉터리의 물리적 주소를 저장하고 있는 CR3 레지스터로부터 값을 읽어와 현재 프로세스의
페이지 디렉터리를 찾는다.(페이지 디렉터리로 이동)
2. 가상 주소의 페이지 디렉터리 인덱스 값에서 현재 프로세스의 페이지 디렉터리의 엔트리를 찾고 그 값을 읽는다.
페이지 디렉터리 엔트리에는 페이지 테이블의 주소 정보가 들어있다.(페이지 테이블로 이동)
3. 페이지 디렉터리의 엔트리에 저장된 페이지 테이블 인덱스 값으로 페이지 테이블 엔트리를 찾아 그 값을 읽는다.
페이지 테이블 엔트리에는 물리적 주소의 페이지 프레임 주소가 들어있다.(페이지 프레임으로 이동)
4. 가상 주소의 마지막 부분에 있는 바이트주소 인덱스를 이용해서 실제 찾고자 하는 물리적 메모리의 주소로 이동하고
필요한 만큼 데이터를 읽는다.
위의 설명을 그림으로 표현하면 아래와 같다.
프로세스마다 페이지 디렉터리를 가지고 있으며 이것의 물리적 주소는 KPROCESS 구조안에 저장되어 있다가 Context Switching이
발생하면 CR3 레지스터로 복사 된다.
실제 프로세스 오브젝트는 가상메모리에서 보이는 것과는 달리 물리적 메모리에 단편화 되어 저장되는데 흩어져 있는
프로세스 데이터를 가장주소를 근거로 찾으려면 반드시 페이지 디렉터리의 물리적 주소가 필요하다.
KPROCESS 구조 안에 페이지 디렉터리의 물리적 주소가 아닌 가상 주소가 저장되어 있다면 가상주소와 물리주소의 맵핑은 불가능하다.
이것을 처음 이해하기에는 조금 힘이 들것이다.
또 위의 그림 4의 과정을 이해하는 것도 처음에는 어려울 것이다.
순서를 하나씩 읽고 그림의 화살표를 따라가다보면 이해에 조금 도움이 될 것이다.
'[+] Forensic' 카테고리의 다른 글
Memory Analysis (8) (3) | 2011.12.28 |
---|---|
Memory Analysis (7) (0) | 2011.12.28 |
Memory Analysis (5) (0) | 2011.12.26 |
Memory Analysis (4) (0) | 2011.12.25 |