📄 jiurl玩玩win2k内存篇 内存共享(一) protopte.htm
字号:
10<BR>0010:E13C9560 04E80121 04E61121 04E13121 04E14121
!...!...!1..!A..<BR>再来看看这个物理页的 PfnDataBaseEntry<BR>:dd 81456000+4e80*18 l
18<BR>0010:814CBC00 00000011 E13C9560 0000000B 00010608
....`.<.........<BR>0010:814CBC10 93E6A478 00001D79 0000003C E13C95DC
x...y...<.....<.<BR>// 共享计数加1了,从 0000000A 变成了
0000000B<BR><BR>这种情况就是一个进程把共享页移出了 Working
Set,于是相应的Pte无效,<BR>但是这个被共享的物理页还在被其他进程使用,所以这个物理页不会被移入 Standby
链,ProtoPte有效,并仍指向而这个物理页。这个进程再次访问这个共享页,只需要把Pte重新指向这个物理页就可以了。MiCompleteProtoPteFault()
的作用就是把ProtoPte中的物理页设置到 Pte 中,并设定 Pte 的低12位标志。</FONT>
<P>
<P><FONT face=宋体>3 PTE无效,高20bit不等于0xfffff。ProtoPte 无效。<BR><BR>Break due to
BPX #0008:8043F6AE DO "dd ebp+c l 10;dd ebp->10 l 10;dd ebp->14
l<BR>10" (ET=22.20 milliseconds)<BR>0010:EB6A7CC4 75951A3F C01D6544
E17BC2C4 EB6A7CFC ?..uDe....{..|j.<BR>// InValidAddress=
75951A3F<BR>0010:C01D6544 01EF0C62 00000000 00000000 00000000
b...............<BR>// Pte= 01EF0C62<BR>0010:E17BC2C4 07889860 0784A860
000000A0 90F4C430 `...`.......0...<BR>// ProtoPte=
07889860<BR><BR>观察物理页7889的PfnDataBaseEntry<BR>:dd 81456000+7889*18 l
18<BR>0010:8150ACD8 00000696 E17BC2C4 000060C7 00000208
......{..`......<BR>0010:8150ACE8 90F4C460 00004E5C 0000790B E2EF088C
`...\N...y......<BR><BR>/*04*/ pteaddress 值为 E17BC2C4 ,正是 ProtoPte
的地址。<BR>/*0D*/ page state 值为 02 ,说明这个物理页状态为 Standby
。<BR><BR>这种情况就是所有共享这个物理页的进程的相应的Pte都已经无效了。于是物理页被移入了 Standby
链,不过 <BR>物理页中的内容仍然保持不变。ProtoPte 仍然指向这个物理页,不过 ProtoPte
无效。<BR><BR>:query 75951a3f<BR>Context Address Range Flags MMCI PTE
Name<BR>NOTEPAD 75950000-75955000 07100001 810F4BA8 E17BC2C0
lz32.dll<BR><BR>从断点继续执行<BR><BR>...<BR>MiResolveTransitionFault()<BR>MiCompleteProtoPteFault()<BR>...<BR><BR>直到
MiResolveProtoPteFault() 返回处<BR><BR>:dd c01d6544 l 10<BR>0010:C01D6544
07889025 00000000 00000000 00000000 %...............<BR>//
Pte变有效了,并且就是前面已经放在 Standby 链上的物理页7889。<BR>:dd e17bc2c4 l
10<BR>0010:E17BC2C4 07889121 0784A860 000000A0 90F4C430
!...`.......0...<BR>// ProtoPte
变有效了。指向物理页7889。<BR>观察物理页7889的PfnDataBaseEntry<BR>:dd 81456000+7889*18 l
18<BR>0010:8150ACD8 0000024A E17BC2C4 00000001 00010608
J.....{.........<BR>0010:8150ACE8 90F4C460 00004E5C 0000790B E2EF088C
`...\N...y......<BR>状态从02变为了06,即从Standby 变为了 Active
(Valid)。<BR>共享计数也变为了1。<BR><BR>这种情况就是,所有共享该物理页的进程都把该共享页从自己的 Working Set
中移出,于是物理页被移入了Standby 链,当一个进程重新访问的时候,只需要根据 ProtoPte 中的信息,把该物理页从 Standby
链移回就可以了。<BR><BR><BR>4 PTE无效,高20bit等于0xfffff。ProtoPte 有效。<BR><BR>Break due
to BPX #0008:8043F6AE DO "dd ebp+c l 10;dd ebp->10 l 10;dd ebp->14
l<BR>10" (ET=2.38 seconds)<BR>0010:EBAD5D44 003C0612 C0000F00 E2F5D0C0
EBAD5D7C ..<.........|]..<BR>0010:C0000F00 FFFFF460 04483025 04440025
04423005 `...%0H.%.D..0B.<BR>0010:E2F5D0C0 043BF163 04483163 04440163
04423163 c.;.c1H.c.D.c1B.<BR>:dd 81456000+43bf*18 l 18<BR>0010:814BB9E8
00002B23 E2F5D0C0 00000002 00010609 #+..............<BR>0010:814BB9F8
000000C0 0000782A 000000D0 C0004F38 ....*x......8O..<BR>:query
3c0612<BR>Context Address Range Flags MMCI PTE Name<BR>NOTEPAD
003A0000-0069F000 03400000 810C3D68 E2F5D040 Heap
(mapped)<BR><BR>...<BR>MiCompleteProtoPteFault<BR>...<BR><BR>:dd c0000f00
l 10<BR>0010:C0000F00 043BF025 04483025 04440025 04423005
%.;.%0H.%.D..0B.<BR>:dd e2f5d0c0 l 10<BR>0010:E2F5D0C0 043BF163 04483163
04440163 04423163 c.;.c1H.c.D.c1B.<BR>:dd 81456000+43bf*18 l
18<BR>0010:814BB9E8 00002B23 E2F5D0C0 00000003 00010609
#+..............<BR>0010:814BB9F8 000000C0 0000782A 000000D0 C0004F38
....*x......8O..<BR><BR>和 PTE无效高20bit不等于0xfffff,ProtoPte 有效
的情况相同。<BR><BR>5 PTE无效,高20bit等于0xfffff。ProtoPte 无效。<BR><BR>Break due to BPX
#0008:8043F6AE DO "dd ebp+c l 10;dd ebp->10 l 10;dd ebp->14 l<BR>10"
(ET=16.16 milliseconds)<BR>0010:EF0B55D4 09C2ACE8 C00270A8 E35C7AA8
EF0B560C .....p...z\..V..<BR>0010:C00270A8 FFFFF420 00000000 00000000
00000000 ...............<BR>0010:E35C7AA8 04D4E8C2 04D4F8C2 04D508C0
04D518C0 ................<BR><BR>:dd 81456000+4d4e*18 l
18<BR>0010:814C9F50 00004D4F E35C7AA8 000068A1 00000208
OM...z\..h......<BR>0010:814C9F60 C79314D8 000048D9 00004D53 E35C7AAC
.....H..SM...z\.<BR><BR>:query 9c2ace8<BR>Context Address Range Flags MMCI
PTE Name<BR>NOTEPAD 09C20000-09C33000 01000000 84793128 E35C7A80
shdocvw.dll<BR><BR>...<BR>MiResolveTransitionFault<BR>MiCompleteProtoPteFault<BR>...<BR><BR>:dd
c00270a8 l 10<BR>0010:C00270A8 04D4E025 00000000 00000000 00000000
%...............<BR>:dd e35c7aa8 l 10<BR>0010:E35C7AA8 04D4E123 04D4F8C2
04D508C0 04D518C0 #...............<BR>:dd 81456000+4d4e*18 l
18<BR>0010:814C9F50 000004B3 E35C7AA8 00000001 00010608
.....z\.........<BR>0010:814C9F60 C79314D8 000048D9 00004D53 E35C7AAC
.....H..SM...z\.<BR><BR>和 PTE无效高20bit不等于0xfffff,ProtoPte 无效
的情况相同。<BR><BR>PTE无效,高20bit等于0xfffff。ProtoPte 无效 的另外一种情况。<BR><BR>Break due
to BPX #0008:8043F6AE DO "dd ebp+c l 10;dd ebp->10 l 10;dd ebp->14
l<BR>10" (ET=297.11 microseconds)<BR>0010:EB9315D4 07E00200 C001F800
E134A040 EB93160C ........@.4.....<BR>// InValidAddress=
07E00200<BR>0010:C001F800 FFFFF480 FFFFF480 FFFFF480 FFFFF480
................<BR>// Pte= FFFFF480<BR>0010:E134A040 90B20CD8 00000000
000E01CE 00000003 ................<BR>// ProtoPte=
90B20CD8<BR><BR>我的物理内存是128M,所以是不会有90B20这么大的物理页帧号的<BR><BR>看看
81456000+90b20*18 地址处的内容<BR>:dd 81456000+90b20*18 l 18<BR>0010:821E6B00
006E006F 00740069 0072006F 8B550000 o.n.i.t.o.r...U.<BR>0010:821E6B10
08EC81EC 56000002 5610758B FF0C75FF
.......V.u.V.u..<BR>明显不是PfnDataBaseEntry<BR><BR>:query 7e00200<BR>Context
Address Range Flags MMCI PTE Name<BR>NOTEPAD 07E00000-07E7F000 04000000
810B20A8 E134A040
~DFD8D0.tmp<BR><BR>从断点继续<BR><BR>...<BR>MiResolveMappedFileFault()<BR>...<BR><BR>直到
MiResolveProtoPteFault() 返回处<BR><BR>:dd c001f800 l 10<BR>0010:C001F800
FFFFF480 FFFFF480 FFFFF480 FFFFF480 ................<BR>:dd e134a040 l
10<BR>0010:E134A040 067A18C0 00000000 000E01CE 00000003
..z.............<BR>:dd 81456000+67a1*18 l 18<BR>0010:814F1718 813E7348
E134A040 00000000 0001000A Hs>.@.4.........<BR>0010:814F1728 90B20CD8
00001BB2 0000242B E2BB014C
........+$..L...<BR><BR>Pte仍然无效,ProtoPte已经指向了一个真正的物理页67a1,<BR>物理页67a1的PfnDataBaseEntry
状态为00,即Zeroed,/*04*/ pteaddress 为 E134A040。<BR><BR>从
MiResolveProtoPteFault() 返回到了 MiDispatchFault()
中,继续执行。<BR><BR>...<BR>IoPageRead()<BR>MiCompleteProtoPteFault()<BR>...<BR><BR>:dd
c001f800 l 10<BR>0010:C001F800 067A1067 FFFFF480 FFFFF480 FFFFF480
g.z.............<BR>:dd e134a040 l 10<BR>0010:E134A040 067A1163 00000000
000E01CE 00000003 c.z.............<BR>:dd 81456000+67a1*18 l
18<BR>0010:814F1718 0000078E E134A040 00000001 00010609
....@.4.........<BR>0010:814F1728 90B20CD8 00001BB2 0000242B E2BB014C
........+$..L...<BR><BR>又看到了 MiCompleteProtoPteFault()
,把ProtoPte的物理页设置到Pte,并把Pte变有效。<BR>物理页67a1的共享计数也变为了1。<BR><BR>6
PTE无效,高20bit等于0xfffff。ProtoPte 无效,并且高20位为0<BR><BR>Break due to BPX
#0008:8043F6AE DO "dd ebp+c l 10;dd ebp->10 l 10;dd ebp->14 l<BR>10"
(ET=1.78 milliseconds)<BR>0010:EB6675D4 07CA0000 C001F280 E354CDE0
EB66760C ..........T..vf.<BR>0010:C001F280 FFFFF480 00000000 00000000
00000000 ................<BR>0010:E354CDE0 00000080 00000000 00100000
00000000 ................<BR>// ProtoPte= 00000080<BR><BR>不过明显 ProtoPte
的高20位并不是共享物理页的页帧号<BR>:dd 81456000+0*18 l 18<BR>0010:81456000 00000000
C0200000 00000001 00010600 ...... .........<BR>0010:81456010 00000000
00000032 00000000 C0200004 ....2......... .<BR>从物理页0的 PfnDataBaseEntry
也看到了 /*04*/ pteaddress 为 C0200000 ,而不是 E354CDE0。<BR>:query
7ca0000<BR>Context Address Range Flags MMCI PTE Name<BR>NOTEPAD
07CA0000-07CA0000 04000000 810B7CC8
E354CDE0<BR><BR>...<BR>MiResolveDemandZeroFault<BR>MiCompleteProtoPteFault<BR>...<BR><BR>:dd
c001f280 l 10<BR>0010:C001F280 068CA067 00000000 00000000 00000000
g...............<BR>:dd e354cde0 l 10<BR>0010:E354CDE0 068CA163 00000000
00100000 00000000 c...............<BR>:dd 81456000+68ca*18 l
18<BR>0010:814F32F0 000005ED E354CDE0 00000001 00010609
......T.........<BR>0010:814F3300 00000080 00004465 000068EC E2BAE934
....eD...h..4...<BR><BR>最后Pte和ProtoPte都变为有效,指向物理页068CA。<BR><BR><BR>7
PTE无效,高20bit不等于0xfffff。ProtoPte
无效,并且高20位为0<BR><BR>为了能比较容易找到这种情况,使用了在下断点时,使用了if,判断条件是否合适<BR>Break due to
BPX #0008:8043F6AE IF (((EBP->0x14)->0)<0x1000)
(ET=510.83<BR>milliseconds)<BR><BR>:dd ebp+c l 10<BR>0010:F057FCC4
01009938 C0004024 E3084564 F057FCFC 8...$@..dE....W.<BR>:dd ebp->10 l
10<BR>0010:C0004024 082114B2 00000000 00000000 00000000
..!.............<BR>:dd ebp->14 l 10<BR>0010:E3084564 000000A0 0381A820
0381B820 0381C820 .... ... ... ...<BR>// ProtoPte 中的高20bit并不是物理页帧号<BR>//
物理页0的PfnDataBaseEntry 也说明了这一点。<BR>:dd 81456000+0*18 l 18<BR>0010:81456000
00000000 C0200000 00000001 00010600 ...... .........<BR>0010:81456010
00000000 00000032 00000000 C0200004 ....2......... .<BR>:query
1009938<BR>Context Address Range Flags MMCI PTE Name<BR>NOTEPAD
01000000-0100F000 07100002 836F8408 E3084540
NOTEPAD.EXE<BR><BR>...<BR><BR>执行几句之后<BR><BR>:dd ebp+c l
10<BR>0010:F057FCC4 01009938 C0004024 00000001 F057FCFC
8...$@........W.<BR>:dd c0004024 l 10<BR>0010:C0004024 00000080 00000000
00000000 00000000 ................<BR>:dd e3084564 l 10<BR>0010:E3084564
000000A0 0381A820 0381B820 0381C820 .... ... ...
...<BR><BR>...<BR>MiResolveDemandZeroFault<BR><BR>:dd ebp+c l
10<BR>0010:F057FCC4 01009938 C0004024 00000001 F057FCFC
8...$@........W.<BR>:dd c0004024 l 10<BR>0010:C0004024 06934067 00000000
00000000 00000000 g@..............<BR>:dd e3084564 l 10<BR>0010:E3084564
000381A820 0381B820 0381C820 .... ... ... ...<BR>:dd 81456000+6934*18 l
18<BR>0010:814F3CE0 000000EF C0004024 00000001 00010601
....$@..........<BR>0010:814F3CF0 00000080 000059F5 00005B36 FFFFFFFF
.....Y..6[......<BR><BR>最后Pte有效。<BR><BR><BR>对 Prototype PTE
的分析就到这里。<BR><BR><BR>欢迎交流,欢迎交朋友,<BR>欢迎访问 <A
href="http://jiurl.yeah.net/">http://jiurl.yeah.net/</A> <A
href="http://jiurl.cosoft.org.cn/forum">http://jiurl.cosoft.org.cn/forum</A>
<BR><BR><BR></FONT>
<P>
<P> </P></TD></TR></TBODY></TABLE></DIV></BODY></HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -