1. 程式人生 > >使用windbg在開啟PAE的情況下將虛擬地址轉化成物理地址

使用windbg在開啟PAE的情況下將虛擬地址轉化成物理地址

技術分享 dir halt cgroup nbsp session bre dog 格式

在開啟PAE之後,32位的線性地址的結構發生了變化,具體結構如下

技術分享

30-31位:頁目錄指針表索引

21-29位:頁目錄索引

12-20位:頁表索引

0-11位:頁內偏移

在開啟PAE之後,表中地址都是物理地址,所有表項的大小變為8Byte,具體格式如下:

技術分享

結合Windows Server 2008中calc.exe中數字的地址分析PAE的地址轉化機制

我們在虛擬機中打開calc.exe,然後輸入“1234567890”,然後我們打開windbg,附加到calc.exe進程中,用“x calc!gp*”查看calc.exe中gp開頭的所有符號的虛擬地址

0:002> x calc!g*
000b4aad calc!GroupDigits = <no type information>
000c4edc calc!ghwndTimeOutDlg = <no type information>
000c4d70 calc!g_fHighContrast = <no type information>
000b5682 calc!GetKeyColor = <no type information>
000c4ecc calc!gfExiting = <no type information>
000b56cc calc!GetHelpID = <no type information>
000c4b80 calc!ghnoPrecNum = <no type information>
000c4be8 calc!ghnoParNum = <no type information>
000c4038 calc!gszSep = <no type information>
000c4ec0 calc!ghcurOld = <no type information>
000c4b6c calc!g_ahnoChopNumbers = <no type information>
000c4ed4 calc!ghCalcDone = <no type information>
000c4d84 calc!gpszNum = <no type information>
000c4ee0 calc!gnPendingError = <no type information>
000c402c calc!gszDec = <no type information>
000c4000 calc!gnDecGrouping = <no type information>
000c4d98 calc!gcio = <no type information>
000c4d6c calc!ghnoLastNum = <no type information>
000c4ed8 calc!ghDogThread = <no type information>
000c4d54 calc!g_hDecMenu = <no type information>
000c4efc calc!gbinexact = <no type information>
000c4d50 calc!g_hHexMenu = <no type information>
000c4ed0 calc!ghCalcStart = <no type information>
000c4d74 calc!g_fLayoutRTL = <no type information>
000c4d90 calc!gbRecord = <no type information>
000c4d88 calc!gcchNum = <no type information>
000c4c4c calc!gcIntDigits = <no type information>
000c4d40 calc!g_hwndDlg = <no type information>
000c4f10 calc!gfHalt = <no type information>
000c4d20 calc!gbUseSep = <no type information>
000c4d68 calc!ghnoMem = <no type information>
000c4f00 calc!gllfact = <no type information>
000c4d64 calc!ghnoNum = <no type information>
000c4070 calc!gldPrevious = <no type informatio

其中calc!gpszNum就是數字的變量名,其虛擬地址為000c4d84,用!dd 000c4d84查看該變量所指向的地址

0:002> dd 000c4d84
000c4d84 00428378 0000000c 00000000 00000001
00428378就是字符串“1234567890”的虛擬地址

0:002> dc 00428378
00428378 00320031 00340033 00360035 00380037 1.2.3.4.5.6.7.8.
00428388 00300039 0000002e 5da02f60 88000000 9.0.....`/.]....
我們使用虛擬地址00428378轉化為物理地址,首先使用.formats命令將該地址轉化為二進制形式

0:002> .formats 00428378
Evaluate expression:
Hex: 00428378
Decimal: 4359032
Octal: 00020501570
Binary: 00000000 01000010 10000011 01111000
Chars: .B.x
Time: Fri Feb 20 18:50:32 1970
Float: low 6.1083e-039 high 0
Double: 2.15365e-317
根據PAE32位線性地址的結構我們得出:

頁目錄指針表索引為 00 = 0x0

頁目錄索引為000000 010 = 0x2

頁表索引為00010 1000 = 0x28

頁內偏移為0011 01111000 = 0x378

我們使用!process 0 0,找到calc.exe的EPROCESS結構體,其中DirBase就是CR3的值,即頁目錄指針表的基地址

PROCESS 8340c9f0 SessionId: 1 Cid: 0a34 Peb: 7ffdd000 ParentCid: 0278
DirBase: 3ed32440 ObjectTable: 8fa64808 HandleCount: 46.
Image: calc.exe
由於CR3低5位值全為0,所以頁目錄指針表基地址為3ed32440,使用!dq 3ed32440查看該表的內容

kd> !dq 3ed32440
#3ed32440 00000000`06a49801 00000000`0698a801
#3ed32450 00000000`0638b801 00000000`0630c801
頁目錄指針表的虛擬地址為0,所以我們要考察的表項為00000000`06a49801

該值的12-35位為頁目錄表的基地址高24位,故頁目錄表的基地址為06a49000,頁目錄索引為0x2,故輸入!dq 06a49000+0x2*8(每個表項大小為8Byte)

kd> !dq 06a49000+0x2*8
# 6a49010 00000000`06b31867 00000000`06d7e867
該值為00000000`06b31867,12-35位為頁表基地址高24位,故頁表基地址為06b31000,頁表索引為0x28,故輸入!dq 06b31000+0x28*8

kd> !dq 06b31000+0x28*8
# 6b31140 80000000`0620b867 00000000`00000000

該值為80000000`0620b867,12-35位為頁面基地址高24位,故頁面基地址為0620b000,頁內偏移為0x378,故輸入!dc 0620b000+0x378

kd> !dc 0620b000+0x378
# 620b378 00320031 00340033 00360035 00380037 1.2.3.4.5.6.7.8.
# 620b388 00300039 0000002e 5da02f60 88000000 9.0.....`/.]....
因此,物理地址為0620b378

使用windbg在開啟PAE的情況下將虛擬地址轉化成物理地址