您的位置:首页 > 博客中心 > 数据库 >

使用windbg在开启PAE的情况下将虚拟地址转化成物理地址

时间:2022-03-06 06:31

在开启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

本类排行

今日推荐

热门手游