세그먼테이션(가상주소->선형주소 변환과정) 페이징(선형주소->물리주소 변환과정)

테스트 대상 가상주소: kbdclass.sys DriverObject.DriverName.Buffer

kd> !drvobj kbdclass
Driver object (866bc030) is for:
 \Driver\Kbdclass
Driver Extension List: (id , addr)

Device Object list:
866b6030  865c6968 
kd> dt _driver_object 866bc030
nt!_DRIVER_OBJECT
   +0x000 Type             : 4
   +0x002 Size             : 168
   +0x004 DeviceObject     : 0x866b6030 _DEVICE_OBJECT
   +0x008 Flags            : 0x12
   +0x00c DriverStart      : 0xf7b8b000
   +0x010 DriverSize       : 0x5c80
   +0x014 DriverSection    : 0x865c7258
   +0x018 DriverExtension  : 0x866bc0d8 _DRIVER_EXTENSION
   +0x01c DriverName       : UNICODE_STRING "\Driver\Kbdclass"
   +0x024 HardwareDatabase : 0x80691a90 _UNICODE_STRING "\REGISTRY\MACHINE\HARDWARE\DESCRIPTION\SYSTEM"
   +0x028 FastIoDispatch   : (null)
   +0x02c DriverInit       : 0xf7b8f610     long  kbdclass!GsDriverEntry+0
   +0x030 DriverStartIo    : (null)
   +0x034 DriverUnload     : (null)
   +0x038 MajorFunction    : [28] 0xf7b8bdd0     long  kbdclass!KeyboardClassCreate+0

kd> dt _UNICODE_STRING (866bc030 + 01c)
nt!_UNICODE_STRING
 "\Driver\Kbdclass"
   +0x000 Length           : 0x20
   +0x002 MaximumLength    : 0x20
   +0x004 Buffer           : 0xe182d4c0  "\Driver\Kbdclass"

가상주소 0xe182d4c0 체크 결과

kd> db 0xe182d4c0 
e182d4c0  5c 00 44 00 72 00 69 00-76 00 65 00 72 00 5c 00  \.D.r.i.v.e.r.\.
e182d4d0  4b 00 62 00 64 00 63 00-6c 00 61 00 73 00 73 00  K.b.d.c.l.a.s.s.
e182d4e0  05 04 08 0c 50 70 73 75-48 b8 82 e1 08 d0 46 e1  ....PpsuH.....F.
e182d4f0  18 c8 46 e1 01 00 00 00-70 1a 83 e1 a8 63 82 e1  ..F.....p....c..
e182d500  18 00 18 00 88 b8 82 e1-67 5c 02 48 00 00 00 00  ........g\.H....
e182d510  3c 27 cc f7 a8 27 cc f7-1c 27 cc f7 d1 84 4f 80  <'...'...'....O.
e182d520  08 04 01 00 4f 62 53 71-01 04 03 0c 47 67 6c 73  ....ObSq....Ggls
e182d530  ea 4f 00 00 01 00 00 00-00 00 ea 4f 80 ba 01 80  .O.........O....

가상주소 0xe182d4c0 선형주소로 변환
주소공간은 DataSection 존재하며 DS (데이터 세그먼트레지스터와 조합

kd> r ds
ds=00000023

kd> .formats 0x23
Evaluate expression:
  Hex:     00000023
  Decimal: 35
  Octal:   00000000043
  Binary:  00000000 00000000 00000000 00100011
  Chars:   ...#
  Time:    Thu Jan 01 09:00:35 1970
  Float:   low 4.90454e-044 high 0
  Double:  1.72923e-322

세그먼트 레지스터는 16-bit 크기로 아래의 포맷으로 사용


00000000 00100011
경우 [00000000 00100] [0] [11] 같이 설정됨

kd> .formats 0y0000000000100
Evaluate expression:
  Hex:     00000004 // GDT INDEX
  Decimal: 4
  Octal:   00000000004
  Binary:  00000000 00000000 00000000 00000100
  Chars:   ....
  Time:    Thu Jan 01 09:00:04 1970
  Float:   low 5.60519e-045 high 0
  Double:  1.97626e-323

GDT 확인

kd> r gdtr (or !pcr)
gdtr=8003f000

kd> dq 8003f000 + 4 * 8 L1  (gdtr + 인덱스 * sizeof(세그먼트 디스크립터))
8003f020  00cff300`0000ffff

GDT 엔트리 (Segment Descriptor) 포맷



위의 내용을 dg 통해 쉽게 있음

kd> dg 0x23 (ds)
                                  P Si Gr Pr Lo
Sel    Base     Limit     Type    l ze an es ng Flags
---- -------- -------- ---------- - -- -- -- -- --------
0023 00000000 ffffffff Data RW Ac 3 Bg Pg P  Nl 00000cf3

선형주소는 Base + 가상주소의 형태가 되며, 여기서 Base 0 이므로 가상주소 = 선형주소가
(
윈도우는 일부 세그먼트레지스터(FS ) 제외하고는 Base 0이므로, 일반적으로 가상주소 = 선형주소의 식이 성립)

계산된 선형주소:

  • 가상주소 : 0xe182d4c0
  • 선형주소 : 0xe182d4c0


선형주소의 포맷

  • [31 - 22: 페이지 디렉토리 인덱스] [21 - 12: 페이지 테이블 인덱스] [11 - 0: 페이지프레임 오프셋]


선형주소 0xe182d4c0 에서 페이지디렉토리 인덱스, 페이지테이블 인덱스, 페이지프레임 오프셋 계산

kd> .formats 0xe182d4c0
Evaluate expression:
  Hex:     e182d4c0
  Decimal: -511519552
  Octal:   34140552300
  Binary:  11100001 10000010 11010100 11000000
  Chars:   ....
  Time:    ***** Invalid
  Float:   low -3.01676e+020 high -1.#QNAN
  Double:  -1.#QNAN

(i)[11100001 10] (ii)[000010 1101] (iii)[0100 11000000] 같이 나뉘며,


(i)    0y1110000110 (0x386),
페이지 디렉토리 테이블은 4바이트 요소를 가지므로, 오프셋은 0x386 * 4 = 0xe18
PAGE DIRECTORY INDEX    : 0x386 (offset 0xe18)

(ii)    0y0000101101 (0x2d),
페이지 테이블은 4바이트 요소를 가지므로, 오프셋은 0x2d  * 4 = 0xb4
PAGE TABLE INDEX    : 0x2d (offset 0xb4)

(iii)    0y010011000000 (0x4c0)
PAGE FRAME OFFSET    : 0x4c0

  1. PAGE DIRECTORY BASE 계산

CR3 레지스터에 저장되어 있음(컨텍스트 스위칭이 발생될때마다 프로세스의 Page directory base 값이 CR3 저장)

kd> r cr3
cr3=00039000

PAGE DIRECTORY BASE: 00039000

 

  1. PAGE TABLE BASE 계산

Page directory base 00039000이고, 위의 (i)에서 page directory offset  0xe18 이므로

kd> dd /p 00039000 + e18 L1 // 이후부터 참조되는 메모리주소는 물리주소이므로 /p 옵션을 사용
00039e18  08edb163

여기서, 페이지 디렉토리 테이블의 요소는 아래와 같은 포맷을 가짐
[31 - 12: PFN (
페이지 프레임 번호) [11 - 0: 기타]

31 - 12 bit BASE 가리키게 되므로

PAGE TABLE BASE : 0x08edb000

 

  1. PAGE FRAME BASE 계산

Page table base 08edb000이고, page table offset  0xb4 이므로

kd> dd /p 0x08edb000 + b4 L1
08edb0b4  08f0d163

마찬가지로, 31 - 12 비트만 보면

PAGE FRAME BASE : 0x08f0d000

 

  1. PHYSICAL ADDRESS 계산

Page frame base로부터 offset 0x4c0 이므로,

TARGET PHYSICAL ADDRESS : 0x08f0d4c0

kd> db /p 0x08f0d4c0
08f0d4c0  5c 00 44 00 72 00 69 00-76 00 65 00 72 00 5c 00  \.D.r.i.v.e.r.\.
08f0d4d0  4b 00 62 00 64 00 63 00-6c 00 61 00 73 00 73 00  K.b.d.c.l.a.s.s.
08f0d4e0  05 04 08 0c 50 70 73 75-48 b8 82 e1 08 d0 46 e1  ....PpsuH.....F.
08f0d4f0  18 c8 46 e1 01 00 00 00-70 1a 83 e1 a8 63 82 e1  ..F.....p....c..
08f0d500  18 00 18 00 88 b8 82 e1-67 5c 02 48 00 00 00 00  ........g\.H....
08f0d510  3c 27 cc f7 a8 27 cc f7-1c 27 cc f7 d1 84 4f 80  <'...'...'....O.
08f0d520  08 04 01 00 4f 62 53 71-01 04 03 0c 47 67 6c 73  ....ObSq....Ggls
08f0d530  ea 4f 00 00 01 00 00 00-00 00 ea 4f 80 ba 01 80  .O.........O....

* 참고 *
nt!NtCreateFile
등의 함수는 실제 물리메모리에 존재하는 것이 아니라 exe파일(ntoskrnl.exe) 자체가 가상메모리 영역에 매핑된 것이므로, 위의 과정으로 확인 불가능

Posted by 울랄라베베
:

카테고리

분류 전체보기 (20)
Kernel programming (13)
User porgramming (2)
Etc... (2)