初試將虛擬位址轉換為實體地址

2021-06-14 23:17:16 字數 3497 閱讀 4712

背景:最近學習張銀奎的《軟體除錯》,看到 2.7.5 節 使用windbg觀察分頁機制,終於看到第乙個可以操作的例子,但始終不能按書上的方式正確的將虛擬位址轉換為實體地址,google一下,終於解決,放到這裡記錄一下。

注:可以看到提示符是:kd,這裡為了避免開兩個windbg,直接使用的是核心除錯除錯虛擬機器裡面的xp sp3:

kd> vertarget

windows xp kernel version 2600 (service pack 3) up free x86 compatible

built by: 2600.xpsp_sp3_gdr.130307-0422

machine name:

kernel base = 0x804d8000 psloadedmodulelist = 0x80555140

debug session time: sun jun 16 16:03:10.609 2013 (utc + 8:00)

system uptime: 0 days 0:03:49.906

一、《軟體除錯》中使用的方式:

1. 首先找到calc!gpsznum這個指標的值,(程序上下文設定部分省略)

kd> x calc!gpsz*

01014db0 calc!gpsznum = kd> dd 01014db0 l1

01014db0 000b55d0

kd> du 000b55d0

000b55d0  "123456778."

kd> .formats 000b55d0

evaluate expression:

hex:     000b55d0

decimal: 742864

octal:   00002652720

binary:  00000000 00001011 01010101 11010000

chars:   ..u.

time:    fri jan 09 22:21:04 1970

float:   low 1.04097e-039 high 0

double:  3.67024e-318

可以看到,虛擬位址000b55d0的也目錄索引(高10位)為0;頁表索引(中間10位)即0xb5;頁內偏移為(低12位)為0x5d0。

kd> !process 0 0 calc.exe

process 81ad6020 sessionid: 0 cid: 0890 peb: 7ffda000 parentcid: 06bc

dirbase: 04940380 objecttable: e1bafd30 handlecount: 45.

image: calc.exe

kd> !dd 04940380  

# 4940380 0aace001 00000000 0ab4f001 00000000

# 4940390 06e50001 00000000 0ab8d001 00000000

# 49403a0 f8da5420 00000000 1ed41001 00000000

# 49403b0 1ecc2001 00000000 1ec3f001 00000000

# 49403c0 f8da53a0 00000000 1e861001 00000000

# 49403d0 1e7a2001 00000000 1e71f001 00000000

# 49403e0 f8da53c0 00000000 05fec001 00000000

# 49403f0 05a6d001 00000000 05cea001 00000000

到這裡,問題就出來了,首先dirbase位址似乎不對,書上、網上、windbg幫助文件上的都是低12位為0,而且在 8.2.11 頁目錄基址 也寫到「dirbase代表的是該程序的頁目錄基位址,即切換到該程序時,cr3暫存器的內容。***因為頁目錄是按4kb邊界對齊的,所以dirbase的低12位總是0。」,但這裡為0x380?然後,該實體地址指向的記憶體值似乎也不對。

kd> !dd 0aace000+b5*4

# aace2d4 00000000 00000000 00000000 00000000

# aace2e4 00000000 00000000 00000000 00000000

# aace2f4 00000000 00000000 00000000 00000000

# aace304 00000000 00000000 00000000 00000000

# aace314 00000000 00000000 00000000 00000000

# aace324 00000000 00000000 00000000 00000000

# aace334 00000000 00000000 00000000 00000000

# aace344 00000000 00000000 00000000 00000000

明顯不對了,實體地址是0x00 ?!

二、使用!pte轉換

最後沒辦法了,在網上搜尋到了另乙個方法:

kd> !pte 000b55d0  

va 000b55d0

pde at c0600000            pte at c00005a8

contains 000000000be42067  contains 800000000a8ae067

pfn be42      ---da--uwev   pfn a8ae      ---da--uw-v

kd> !dd a8ae5d0

# a8ae5d0 00320031 00340033 00360035 00370037

# a8ae5e0 002e0038 00000000 00040004 000c0198

# a8ae5f0 00000000 00340033 00360035 00370037

# a8ae600 0000002e 000a246a 00040153 00000010

# a8ae610 000b4190 000a0178 00200001 000a246a

# a8ae620 00000000 00000000 00000020 000a246a

# a8ae630 00000000 00000010 00000010 00000002

# a8ae640 00010001 000a246a 00000000 00000000

kd> !du a8ae5d0

# a8ae5d0 "123456778."

在右欄最後一列看到記號「pfn a8ae」出現。數值0xa8ae是這個pte的page frame number (pfn)。把頁框架號乘以0x1000 (例如,把它左移12位)。所得乘積0x0a8ae000是頁開始的實體地址。 

三、手動轉換:

注:後面這兩個方法引用自:

課上練習 手工將虛擬位址轉換為實體地址

環境設定 關閉pae 實體地址擴充套件 bcdedit set pae forcedisable bcdedit set nx alwaysoff 開啟雙機除錯,在虛擬機器中新建乙個記事本,並輸入 cyxvc 然後斷下來 在windbgm中輸入 0 kd process 0 0 notepad.ex...

虛擬位址與實體地址

乙個程式編譯連線後形成的位址空間是乙個虛擬位址空間,但是程式最終還是要執行在物理記憶體中。因此,應用程式所給出的任何虛位址最終必須被轉化為實體地址,所以,虛擬位址空間必須被對映到物理記憶體空間中,這個對映關係需要通過硬體體系結構所規定的資料結構來建立。這就是我們所說的段描述符表和頁表,linux主要...

邏輯位址 實體地址 虛擬位址

用於記憶體晶元級的單元定址,與處理器和cpu連線的位址匯流排相對應。雖然可以直接把實體地址理解成插在機器上那根記憶體本身,把記憶體看成乙個從0位元組一直到最大空量逐字節的編號的大陣列,然後把這個陣列叫做實體地址,但是事實上,這只是乙個硬體提供給軟體的抽像,記憶體的定址方式並不是這樣。所以,說它是 與...