Theory/Forensic

메모리 수집 분석

D4tai1 2019. 1. 19.

 

1. Windows Memory 이해

(1) Virtual Address Space (VAS)

 [1] VAS는 실제 Physical Memory를 mapping한 가상 주소를 사용하는 것으로 Physical Memory 한계를 극복할 수 있고 OS가 메모리 접근을 관리하여 Memory Protection(같은 주소라도 실제 사용하는 주소는 다르다)을 가능하게 한다.

 

 [2] Windows는 VAS를 Physical Memory와 mapping하기 위하여 page table을 사용하며 Physical Memory에 저장할 수 없는 Memory 정보는 pagefile로 저장하게 된다.

 

 [3] [C:\pagefile.sys]와 같이 pagefile로 저장한 것을 페이징(paging)이라고 한다.

 

 [4] Process의 메모리 공간은 공유되지 않는 한 다른 Process가 접근하지 못한다.

 

 [5] 32bit 환경에서는 최대 VAS는 4GB이고 64bit 환경에서는 2의 64bit 만큼의 VAS를 가질 수 있다.

 

 [6] 단, 4기가가 넘어가면 메모리에서 접근이 불가능하다.

 

 [7] 프로세스가 메모리공간을 많이 차지해서 malloc으로 동적할당해도 전부사용하지 않고 쓰는만큼만 사용한다. (이것은 OS가 통제한다.)

 

 [8] 커널메모리는 커널만 접근이 가능하다.

 

 [9] 사용자프로세스가 커널프로세스를 요청해서 커널메모리를 사용한다.

 

 [10] 4기가 중 2기가는 프로세스, 2기가는 시스템에서 사용한다.

 

(2) 메모리

 [1] Heap은 동적메모리를 할당하는 것을 말한다.

 

 [2] Stack은 복귀메모리주소, 매개변수 등을 저장한다.

 

 [3] 메모리 매핑은 커널영역의 라이브러리를 호출한다.

 

 [4] static memory 할당은 전역변수를 선언한거와 비슷하다

 

 [5] usermemory 커널에 있는 변수는 내부에서 버퍼이동해야하는데 사용자 프로세스는 커널메모리에 접근이 불가하다. 
 

 [6] 커널프로세스는 커널메모리에 접근이 가능하므로 커널메모리에 있는 것은 유저메모리 영역에 저장할 수 있다.

 (이것은 OS가 관장한다.)

 

 [7] 프로세스영역 Fopen을 Fn_open()의 커널프로세스가 읽고 커널메모리가 유저메모리에 저장해서 프로세스가 사용한다.

 (드라이버개발은 visual studio 샘플이 많아서 개발하면 내부구조 알기 좋다.)

 

 [8] 커널메모리는 공통이다.

 

 [9] 유저는 접근할 수 없다.

 

 [10] 보통 주소값이 높으면 커널영역, 주소값이 낮으면 프로세스영역으로 구분한다.(디버깅시 확인가능)

 

 [11] 그러나 커널영역주소도 가상주소이고 실제주소는 아니다.

 

 [12] 커널메모리로의 접근

  ▶ 맨 우측 그림 2개(상, 하)의 메모리는 실제로 좌측 2번째 그림과 같이 유저메모리는 공유하지 않지만 커널메모리는 서로 공유한다.
  ▶ 유저가 커널메모리를 접근하게되면 커널메모리를 공유하기에 다른 사용자 영역의 메모리를 침범할수 있기에 유저->커널메모리 접근은 불가하다.

 

  [13] 16비트와 32비트

  ▶ 16비트는 메모리 주소가 같으면 같은 곳을 가르키지만, 32비트는 메모리 주소가 같아도 가상의 주소로 판단한다.

  ▶  os를 거치면 실제 메모리의 다른 곳을 가르키게 된다.

 

 [14] 태스크의 가상메모리주소와 실제메모리주소 매핑

  ▶ PEN은 Page Frame Number를 의미한다.

  ▶ P는 Present(페이지 존재여부)를 의미한다.

  ▶ page table의 일부 = page table entry(4byte) = 실제물리적주소가 저장된다.

  ▶ VAS(4GB, 2^32)의 0번 페이지의 실제주소는 0X0005000 이다.

  ▶ 0X0100은 뒤에 3개 지우고 페이지넘버 0의 페이지주소를 찾아간다,

  ▶ 4번째가 0이므로 페이지주소가 0이고 오프셋 값은 100이된다,

  ▶ 4K(4096, 0X1000)는 물리주소.에 OFFSET 0X100해서 0X1100을 접근한다.

  ▶ 페이지테이블은 메모리의 일부에 존재하고, vas실제로 존재하는 것은 아니다.

  ▶ 접근한 메모리가 0x1100이면 4k씩 끊기에 페이지테이블의 1번테이블로 가서

  ▶ 거기에 있는 주소로 찾아가서 0x1100에서 16진수 천의자리를 뺀 0x0100을 offset값으로 사용한다.

  ▶ 페이지하나하나가 2의 20승이다.

  ▶ 페이지폴트 = 페이지가 물리주소에 할당되어있지 않아 발생.

  ▶ 커널은 실제(물리)메모리의 빈 곳을 하나 할당받아 페이지테이블에 적제된 페이지를 기록하는 하고 다시접근하게 하는 것을

  ▶ demand(요청) paging 이라고 한다.

  ▶ 실제(물리)메모리가 꽉 찰 경우 페이지를 할당할 수 없기에 사용하지 않는 것을 c:\pagefile.sys에 저장하고 필요할 경우 다시 불러와서 사용한다.

  ▶ 2의 32승 / 1024개 = 2의 22승개의 블록

  ▶ 페이지디렉토리는 각 블록의 정보를 지칭한다.

  ▶ 페이지 테이블의 위치정보(실제메모리 4바이트*1024)의 페이지(엔트리의개수) 엔트리[각각 4byte]가 1024개

  ▶ 엔트리하나는 0페이지는 0번 테이블에 대한 주소값을 가지고 있다.

  ▶ 0번페이지테이블에는 실제 물리데이터의 주소가 들어있다.

  ▶ 페이지테이블사이즈는 4메가(2의 10승 x 2의 10승 x 4byte(엔트리하나)]이다.

  ▶ 프로세스하나를 생성시 4메가가 저장된다.

  ▶ 페이지테이블은 반드시저장될 필요가 없다.

  ▶ 4.4메가가 필요하지만? 최소 4메가만 있으면 된다.

  ▶ 주저리주저리 적었지만 아래 내리면 조금 더 정리가 된 내용이 있을 것이다~

 

 [15] 하나의 Page Table을 사용하는 가상 주소 (앞 그림 설명)
  ▶ 하나의 Task에 할당된 Virtual Memory를 Page(4KB)로 분리했을때 n개(0 ~ n-1)의 page가 존재하고, 일반적인 Virtual Memory
Size가 4GB(32bit 기준)라고 할 때 n은 1,048,756(2의 20승)이 된다.

 

  ▶ 2의 32승 = 2의 12승(1page=4096byte) * 2의 20승

 

  ▶ 결국 하나의 Task에 대하여 Page Table Entry가 4byte(Page가 존재하는 주소 저장 공간)인 4MB(1MB * 4byte)의 Page Table 필요하다.

 

  ▶ 현재 분할된 페이지 가운데 페이지 번호 0, 2, 3의 페이지가 실제 물리 메모리에 적재되어 있다.

 

  ▶ 가상주소 0x100에 대한 실제 물리 주소는 가상주소 0x100은 Page Number가 0이고 Offset이 0x100이 된다.

 

  ▶ Page Number 0에는 PFN 0에 해당되고 PFN 0에는 4K(0x1000)라고 하는 물리 주소가 존재한다.

 

  ▶ 따라서 가상주소 0x100의 실제 물리 주소는 0x1100으로 계산된다.

 

 [16] 가상주소 0x1001에 대한 실제 물리 주소

  ▶ 가상주소 0x1001은 Page Number가 1이고 Offset이 0x001이 된다.

 

  ▶ Page Number 1에는 P가 0으로 Page가 할당되어 있지 않는다.

 

  ▶ Page가 물리 주소에 할당되어 있지 않아 페이지 폴트(page Fault) 발생한다.

 

  ▶ 이 때 커널은 물리 메모리의 빈 페이지 프레임 중 하나를 요구하여 할당받고, 해당 페이지를 적재한 후 페이지 테이블에 적재된 페이지 프레임의 위치를 기록하고, 다시 변환 과정을 거쳐 접근하는 것을 Demand paging 기법이라 한다.

 

 [17] I386 페이징 기법 (32bit)


  ▶ 페이지 디렉토리는 각 테스크마다 하나씩 할당되며 10bit를 가지므로 1,024개의 엔트리를 갖는다.

 

  ▶ 각 엔트리는 32bit 주소를 가리키기 위한 4byte 위드 크기를 가지므로 페이지 디렉토리 하나의 크기는 4KB이다.

 

  ▶ 페이지 디렉토리의 각 엔트리는 하나의 페이지 테이블를 가리킨다.

 

  ▶ 따라서 하나의 테스크는 최대 1,024개의 페이지 테이블을 가질 수 있다.

 

  ▶ 그러나 테스크가 생성된다고 무조건 1,024개의 페이지 테이블이 만들어지지 않으며 사용하지 않는 영역에 대해서는 페이지 테이블을 생성하지 않는다.

 

  ▶ 하나의 페이지 테이블 크기는 10bit로서 4KB이고 1,024개의 엔트리를 갖는다.

 

  ▶ 각 페이지 테이블 엔트리는 물리 메모리의 페이지 프레임 주소 정보를 가지고 있다.

 

 [18] EProcess [프로세서 생성시 이 구조체에 저장]

  ▶ 프로세스가 생성되면 해당 프로세스의 정보를 가지고 있는 EPROCESS 라는 구조체가 커널 메모리에 생성된다.


  ▶ 모든 프로세스는 각자의 EPROCESS 구조체를 하나씩 가지고 자신이 사용하는 쓰레드(프로세스가 멀티테스킹을 위해 시간을 분할해서 작업을 하는데 잘게 쪼개진 일의 단위)의 개수만큼 ETHREAD 구조체를 가진다.


  ▶ EPROCESS 와 ETHREAD 내부에는 각각 PCB, TCB란 이름의 KPROCESS 와 KTHREAD 라는 구조체가 존재한다.


  ▶ KPROCESS 는 NULL 동기화 객체와 관련된 디스패처 객체 헤더, 가상메모리의 CR3(페이지디렉토리 주소) 레지스터 값,  프로세스에 속해 있는 스레드 리스트를 말한다.


  ▶ 헤더, CPU에 대한 종속성(Affinity), 프로세스 우선순위, 프로세스에서 생성되는 스레드의 기본 실행 시간 값 등과 같은 정보 저장한다.


  ▶ KTHREAD 는 스레드 종료 동기화 객체, TEB(Thread Environment Block) 포인터, 스레드 우선순위, 스케줄러에 의해 실행을 준비하고 있는 스레드 리스트, 퀀텀 값등의 정보를 저장한다.

※ 추가정보

  ▶ 각각의 프로세스는 서로 다른 메모리공간을 가지고 있어서 프로세스간 데이터를 전송할 수 없다.

 

  ▶ process라는 글로벌을 만들어서 메모리를 공유한다. pt1, pt2 글로벌을 공유해서 pt3는 화면상에 표현해준다.


  ▶ 리눅스에서는 프로세스가 동작하지만, 윈도우에서는 쓰레드가 동작한다. 쓰레드 끼리는 메모리를 공유한다.


  ▶ 윈도우는 다른프로세스의 글로벌에 쓰레드가 붙어서 접근할 수 있다.

 

'Theory > Forensic' 카테고리의 다른 글

실시간 대응  (0) 2019.04.27
레지스트리 분석  (0) 2019.01.19
사이버포렌식 절차  (0) 2018.09.16
사이버포렌식 개론  (0) 2018.09.16
사이버포렌식 기술  (0) 2018.09.16

댓글