-
-
[原创]windbg验证win32逻辑地址,线性地址
-
发表于: 2016-10-18 17:14 4286
-
作为一名新手,经常被什么逻辑地址,线性地址,物理地址搞得晕头转向,很是恼火。
今天狠下心来好好看了下Intel手册才豁然开朗,分享一篇。线性地址和物理地址转换还不怎么懂,会了再发。
====================
这里不会讲很多概念性的东西,直接实验。
逻辑地址:段选择子:偏移量
线性地址:由逻辑地址转化而来,通过段选择子->找段描述符->找基地址,基地址+偏移量就是线性地址。
物理地址:就是真实内存地址,与你机器内存大小有关。
讲了那么多现在开始试验,随便打开一个程序,windbg载入:
eax=00000000 ebx=00000000 ecx=42880000 edx=0010e228 esi=fffffffe edi=00000000
eip=77ad0e14 esp=001cf398 ebp=001cf3c4 iopl=0 nv up ei pl zr na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000246
ntdll!LdrpDoDebuggerBreak+0x2c:
77ad0e14 cc int 3
cs:0023; fs:0053;ss,ds,es,gs都是002b;
逻辑地址转化线性地址(试验1):
随便查看逻辑地址内容:
0:000> dd cs:77a30040
0023:77a30040 0eba1f0e cd09b400 4c01b821 685421cd
0023:77a30050 70207369 72676f72 63206d61 6f6e6e61
0023:77a30060 65622074 6e757220 206e6920 20534f44
0023:77a30070 65646f6d 0a0d0d2e 00000024 00000000
0023:77a30080 bef09ff5 ed9efeb1 ed9efeb1 ed9efeb1
0023:77a30090 ed0c86b8 ed9efeb0 ed0b86b8 ed9efef0
0023:77a300a0 ed1a86b8 ed9efe83 ed1d86b8 ed9eff85
0023:77a300b0 ed0a86b8 ed9efeb0 ed0f86b8 ed9efeb0
看第一列,23代表段选择子,冒号后面就是偏移量。
拿到逻辑地址内容,如何转换为线性地址?
记住公式:线性地址=基址+偏移量。
偏移量我们知道了是77a30040,基地址要从段描述符找,windbg有个dg命令可以查看段描述符。
0:000> dg cs
P Si Gr Pr Lo
Sel Base Limit Type l ze an es ng Flags
---- -------- -------- ---------- - -- -- -- -- --------
0023 00000000 ffffffff Code RE Ac 3 Bg Pg P Nl 00000cfb
字段base就是基址,00000000;
线性地址=00000000+77a30040;再用windbg查看,数据一样,验证成功。
0:000> dd 77a30040
77a30040 0eba1f0e cd09b400 4c01b821 685421cd
77a30050 70207369 72676f72 63206d61 6f6e6e61
77a30060 65622074 6e757220 206e6920 20534f44
77a30070 65646f6d 0a0d0d2e 00000024 00000000
77a30080 bef09ff5 ed9efeb1 ed9efeb1 ed9efeb1
77a30090 ed0c86b8 ed9efeb0 ed0b86b8 ed9efef0
77a300a0 ed1a86b8 ed9efe83 ed1d86b8 ed9eff85
77a300b0 ed0a86b8 ed9efeb0 ed0f86b8 ed9efeb0
这种将base(基地址)设为0,limit(长度)设为整个物理内存空间大小的段使用方式成为平坦模型。换句话说cs,es,ds,gs,ss段使用的是平坦模型,使用这种模型的后果就是,我们程序员在设计程序的时候不必关心分段机制,
观察同一个windows系统中的其他进程,你会发现其他进程的cs,ds,es,gs的值和上面的一模一样,这说明多个进程是共享GDT表中的段描述符的,这是因为使用了平坦模型后,大家的基地址、边界都一样,属性也一样,因此没必要建立多个。
扯远了,如果上面的例子,你还会有点晕晕乎乎的,那么下面这个逻辑地址转化为线性地址的例子肯定会让你豁然开朗。
逻辑地址转化线性地址(试验2):
查看fs:1040的内容,这里逻辑地址的偏移量为1040
0:000> dd fs:1040
0053:00001040 77b34250 00000001 00000000 7efe0000
0053:00001050 00000000 7efe0a90 7efa0000 7efa0000
0053:00001060 7efd0028 00000004 00000070 00000000
0053:00001070 079b8000 ffffe86d 00100000 00002000
0053:00001080 00010000 00001000 00000001 00000010
0053:00001090 77b34760 00000000 00000000 00000000
0053:000010a0 77b320c0 00000006 00000001 01001db1
0053:000010b0 00000002 00000003 00000006 00000000
查看fs段描述符的基地址
0:000> dg fs
P Si Gr Pr Lo
Sel Base Limit Type l ze an es ng Flags
---- -------- -------- ---------- - -- -- -- -- --------
0053 7efdd000 00000fff Data RW Ac 3 Bg By P Nl 000004f3
公式:线性地址=基地址+偏移量 ==》7efdd000+1040=7EFDE040
查看7EFDE040,内容一样验证成功。
0:000> dd 7EFDE040
7efde040 77b34250 00000001 00000000 7efe0000
7efde050 00000000 7efe0a90 7efa0000 7efa0000
7efde060 7efd0028 00000004 00000070 00000000
7efde070 079b8000 ffffe86d 00100000 00002000
7efde080 00010000 00001000 00000001 00000010
7efde090 77b34760 00000000 00000000 00000000
7efde0a0 77b320c0 00000006 00000001 01001db1
7efde0b0 00000002 00000003 00000006 00000000
换句话说逻辑地址fs:1040对应的是线性地址7EFDE040
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课