본문 바로가기

reversing

windows paging - x86, 64

windows paging - x86, 64

윈도우 운영체제는 가상 메모리를 사용한다.

디버깅을 경험해봤다면 프로그램이 대부분 0x400000의 주소부터 시작하는 것을 볼 수 있는데, 이렇게 동일한 주소에 접근해도 데이터가 프로세스별로 다를 수 있는 것은 바로 가상 메모리 때문이다.

0x400000이라는 주소는 논리 주소가 세그멘테이션된 선형 주소이다.

선형 주소는 비트별로 나뉘어 페이징을 통해 물리적 주소가 되고, 이 물리적 주소가 실제 메모리 주소가 된다.

우리가 디버거에서 보는 주소는 가상 주소, 즉 선형 주소이기 때문에 각 프로세스별로 동일한 메모리에 접근해도 값이 상이할 수 있는 것이다.

논리 주소 -> 선형 주소

선형 주소 -> 물리 주소

AMD64paging은 다소 복잡하게 진행될 수 있다.

선형 주소를 각각 정해진 비트로 나누어 이를 테이블의 index로 사용하게 된다.

단계별로 나누어 간단하게 살펴보자.

  1. cr3 레지스터로부터 PML4T의 주소를 얻는다.

  2. PML4T에서 선형 주소의 47~39번째 비트를 이용하여 이를 indexPML4E를 구한다.

  3. PML4E로부터 PDPT의 주소를 얻는다.

  4. PDPT에서 38~30번째 비트를 이용하여 이를 indexPDPE를 구한다.

  5. PDPE로부터 PDT의 주소를 구한다.

  6. ...

  7. PTE로부터 물리 주소를 얻는다.

page tablepage table entry에는 각각 물리 주소가 쓰여져 있고, 각각의 entrypage in, page out에 대한 정보가 쓰여 있어 이를 통해 메모리에 넣었다가 뺏다가 하는 식이다.

사실 x86 버전도 설명하려 했지만, 다른 부분은 x86에는 PML4T, PDPT 단계가 존재하지 않고 PDE부터 시작한다는 점이다.

32bit
CR3 -> PDE -> PTE -> Pysical Address
64bit
CR3 -> PML4E -> PDPE -> PDE -> PTE -> Pysical Address

위와 같이 간단히 이해하고 넘어가면 편안하다.

이 외에도, 각 엔트리마다 비트별로 속성도 정해져있다.

아래의 그림을 참고하자.


R/W 비트가 1이면 Writable, 0이면 Read-Only이다.

P 비트가 1이면 Page-in, 0이면 Page-out이다.

실제로 windbg에서 실습하려면, virtualkd와 같은 것을 이용하여 kernel debbuging을 진행하면 되는데, 이와 관련해 windbg extension!pte가 있고, 손으로 직접 계산하려면 .formats를 이용하면 편하다.

추가적으로,

바로 물리 주소를 확인하고 싶으면 dq /p 명령어를 사용하면 된다.

물리 주소를 dump하고 싶으면 !dq 명령어를 사용하면 된다.

REF

http://esos.hanyang.ac.kr/tc/2015gradproject2/i/entry/4

http://pds24.egloos.com/pds/201202/27/51/amd.pdf

루트킷, 윈도우 커널 조작의 미학

'reversing' 카테고리의 다른 글

EPROCESS(PEB), ETHREAD(TEB), KPROCESS(PCB), KTHREAD(TCB)  (0) 2020.07.30
segmentation  (0) 2020.07.24