윈도우 운영체제는 가상 메모리를 사용한다.
디버깅을 경험해봤다면 프로그램이 대부분 0x400000
의 주소부터 시작하는 것을 볼 수 있는데, 이렇게 동일한 주소에 접근해도 데이터가 프로세스별로 다를 수 있는 것은 바로 가상 메모리 때문이다.
0x400000
이라는 주소는 논리 주소가 세그멘테이션된 선형 주소이다.
선형 주소는 비트별로 나뉘어 페이징을 통해 물리적 주소가 되고, 이 물리적 주소가 실제 메모리 주소가 된다.
우리가 디버거에서 보는 주소는 가상 주소, 즉 선형 주소이기 때문에 각 프로세스별로 동일한 메모리에 접근해도 값이 상이할 수 있는 것이다.
논리 주소 -> 선형 주소
AMD64
의 paging
은 다소 복잡하게 진행될 수 있다.
선형 주소를 각각 정해진 비트로 나누어 이를 테이블의 index
로 사용하게 된다.
단계별로 나누어 간단하게 살펴보자.
cr3
레지스터로부터PML4T
의 주소를 얻는다.PML4T
에서 선형 주소의47~39
번째 비트를 이용하여 이를index
로PML4E
를 구한다.PML4E
로부터PDPT
의 주소를 얻는다.PDPT
에서38~30
번째 비트를 이용하여 이를index
로PDPE
를 구한다.PDPE
로부터PDT
의 주소를 구한다....
PTE
로부터 물리 주소를 얻는다.
page table
의 page table entry
에는 각각 물리 주소가 쓰여져 있고, 각각의 entry
에 page 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 |