天天看點

[windows核心]頁目錄表基址/頁表基址一.頁目錄表基址二.頁表基址

如果系統要保證某個線性位址是有效的,那麼必須為其填充正确的PDE與PTE.

如果我們想填充PDE與PTE,那麼必須能夠通路PDT與PTT,這樣就存在2個問題:

  1. 系統已經為我們通路PDT與PTT挂好了PDE與PTE,我們隻用找到這個線性位址就可以了
  2. 系統是怎麼幫我們挂好PDE與PTE的?

注意:

CR3中存儲的是實體位址,不能在程式中直接讀取的。如果想讀取,也要把Cr3的值挂到PDT和PTT中才能通路,那麼怎麼通過線性位址通路PDT和PTT呢?

一.頁目錄表基址

頁目錄表基址 = 線性位址:0xC0300000

怎麼來論證這個

0xC0300000

就是PDT的基址呢

首先随便找一個程序

[windows核心]頁目錄表基址/頁表基址一.頁目錄表基址二.頁表基址

拆分

0xC0300000

,尋找對應的實體頁

0xC0300000

1100 0000 0011 0000 0000 0000 0000 0000

1100 0000 00   //0x300
11 0000 0000   //0x300
0000 0000 0000 //0x0
           
[windows核心]頁目錄表基址/頁表基址一.頁目錄表基址二.頁表基址

可以發現 實體頁的内容 與 PDT表的内容 完全相同

是以我們可以得出結論

  1. 線性位址C0300000對應的實體頁就是頁目錄表
  2. 這個實體頁即頁目錄表本身也是頁表
  3. 這個實體頁是一張特殊的頁表,每一項PTE指向的不是普通的實體頁,而是指向其它的頁表
  4. 通路頁目錄表的公式:C0300000 + PDI*4(I=index)
    [windows核心]頁目錄表基址/頁表基址一.頁目錄表基址二.頁表基址

二.頁表基址

上面我們找到了PDT的基址,但如果我們要設定某個線性位址的PDE和PET那麼還要能夠通路PTT,那麼如何通路呢?

頁表基址 = 線性位址:0xC0000000

還是那個程序,這是PDT裡的三張PTT表的基址

[windows核心]頁目錄表基址/頁表基址一.頁目錄表基址二.頁表基址

拆分

0xC0000000

十六進制:
	0xC0000000
	
	1100 0000 00   //0x300
	0000 0000 00   //0x0
	0000 0000 0000 //0x0
           
[windows核心]頁目錄表基址/頁表基址一.頁目錄表基址二.頁表基址

可以發現 每一項PTE所指向的實體頁的内容 與 每一個PDE所指向的PTT表的内容完全相同

檢視線性位址C0001000對應的PTT表

0xC0001000

1100 0000 0000 0000 0001 0000 0000 0000

1100 0000 00   //0x300
00 0000 0001   //0x1
0000 0000 0000 //0x0
           
[windows核心]頁目錄表基址/頁表基址一.頁目錄表基址二.頁表基址

發現線性位址C0001000指向的PTT表的第1項PTE為線性位址0xC0000000指向的PTT表的第2項PTE

通過上述的實驗我們總結一下可以得知

  1. 其實頁目錄表(PDT)本不存在,是抽象出來的.
  2. 頁表被映射到了從0xC0000000到0xC03FFFFF的4M位址空間
  3. 在這1024個表中有一張特殊的表:頁目錄表(PDT)
  4. 頁目錄被映射到了0xC0300000開始處的4K位址空間
  5. 通路頁表的公式:

    0xC0000000 + PDI*4096 + PTI*4(I=index)

還是上面這個圖

[windows核心]頁目錄表基址/頁表基址一.頁目錄表基址二.頁表基址

總結

  1. 有了

    0xC0300000

    0xC0000000

    能做什麼:

    掌握了這兩個位址,就掌握了一個程序所有的實體記憶體讀寫權

  2. 公式總結:

    通路頁目錄表的公式:

    C0300000 + PDI*4(I=index)

    通路頁表的公式:

    0xC0000000 + PDI*4096 + PTI*4(I=index)