2021-05-12 14:32:11
在 Linux x86-64 模式下分析記憶體對映流程
前言
在上一篇中我們分析了 Linux 在 x86-32 模式下的虛擬記憶體對映流程,本章主要繼續分析 Linux 在 x86-64 模式下的虛擬記憶體對映流程。
討論的平台是 x86-64, 也可以稱為 AMD64, IA-32e, 是現在廣泛使用的 64 位架構,可以向前相容 16位元和 32 位的 x86. 另外一種獨立的 64 位架構 IA-64與現有架構不同而且貌似發展不好,一般是接觸不到的,我們平常討論的 64 位基本就是指 x86-64.
現在的 CPU 基本都是支援 64 位的,根據處理器強大的相容性,我們可以設定為 long mode 和 legacy mode, 根據安裝的作業系統的模式可以使用不同的模式。
從 wikipedia 的截圖可以看出, 我們下面要測試的是 Operating mode = Long mode, Operating sub-mode = 64-bit mode 下的虛擬記憶體對映流程。
對映流程簡述
分段的存在更多就是為了相容性,所以在 x86-64 下的 64位元程式該功能近似於 bypass。處理器預設 CS, DS, ES, SS的段基址為 0,所以我們下面就不討論邏輯地址到線性地址的轉換了,因為基址為0,經過運算後線性地址和邏輯地址是一樣的,和上一章的扁平模式一樣。
分頁過程會將 48-bit 的線性地址轉換為 52-bit 的實體地址, 可以看出雖然是 64bit 的作業系統但在處理器層面並沒有提供 2^64 大小的存取範圍。48-bit 線性地址可以有以下 3 種對映分配.
4-KByte 頁面
2-MByte 頁面
1-GByte 頁面
我們暫時還不知道 linux 使用哪種分頁,但是知道了每種模式下各個暫存器和page structure entry的格式,可以下面慢慢分析。
格式
驗證方案
本文整個流程參考了網上的另一篇文章,我會在文章末尾列出連結。
整個驗證流程和上一篇在 x86-32 下的測試流程一樣,這裡就不說明了。
驗證過程
編譯載入
編譯檔案,載入 sys_reg.ko, phy_mem.ko 模組
執行 running-prog
執行後可以得到以下輸出:
可以看到變數 a, 這就是我們要尋找實體地址的變數,我們給變數 a 賦了個特殊值方便確認。由於我的作業系統和 running-prog 都是64位元的,所以對 a 的地址翻譯是遵循 x86-64 下的機制的。a 的邏輯地址已經列印出來,而且也就是 a 的線性地址,我們先將 48bit 的線性地址分段.
PML4
控制暫存器 CR3 儲存的是 PML4 的基址, bits 47~39 為 PML4E 的序號,對應的 PML4E 地址為:
0x275A1000 + 0 * 8 = 0x275A1000
PML4E 的值為 0x275DA067.
PDPT
PDPT 的基址為 0x275DA000, bits 38~30 為 PDPTE 序號,計算出的 PDPTE 地址為:
0x275DA000 + 0 * 8 = 0x275DA000
PDPTE 的值為 0x623A4067, bit7 = 0 說明指向的是 page directory.
PD
PD 的基址為 0x623A4000, bits 29~21 為 PDE 的序號,計算出 PDE 的地址為:
0x623A4000 + 3 * 8 = 0x623A4018
PDE 的值為 0x692BB067, bit7 = 0 說明指向的是 page table.
PT
PT 的基址為 0x692BB000, bits 20 ~12 為 PTE 的序號, 計算出 PTE 的地址為:
0x692BB000 + 1 * 8 = 0x692BB008
PTE 的值為 0x800000004AD6F867.
page frame
page frame 的基址為 0x4AD6F000, bits 11~0 為在 page frame內的偏移,計算出變數的實體地址為:
0x4AD6F000 + 120 = 0x4AD6F078.
熟悉的 0xA5A5AA550000FFFF, 說明我們找到了變數 a 的實際實體地址。
結束
感謝 Linux核心在x86_64 CPU中地址對映 一文,我的整個流程參考了原作者的文件和程式碼, 再次感謝原作者的分享。
下面是原始碼下載.study-linux-vm-64bit
------------------------------------------分割線------------------------------------------
免費下載地址在 http://linux.linuxidc.com/
使用者名稱與密碼都是www.linuxidc.com
具體下載目錄在 /2015年資料/2月/8日/在 Linux x86-64 模式下分析記憶體對映流程/
下載方法見 http://www.linuxidc.com/Linux/2013-07/87684.htm
------------------------------------------分割線------------------------------------------
使用方式
make
make install
載入模組
sudo insmod ./output/sys_reg.ko
sudo insmod ./output/phy_mem.ko
running-prog
./output/running-prog
read-phy-mem
因為讀寫 /dev/phy_mem 裝置的許可權問題請使用 sudo 執行.
sudo ./read-phy-mem addr len
status
本程式在 x86-64 linux mint 17, kernel 3.13.0-24 模式下測試通過.
相關文章