深入理解Windows頁幀號(一)
來自專欄嘶吼RoarTalk5 人贊了文章
Windows頁幀號(Page Frame NuMer ,PFN)介紹
Windows以及幾乎所有操作系統都會使用PFN資料庫 ( PFN DataBase ) ,以便跟蹤虛擬分配的頁面,進一步管理哪些頁面要被寫入或移出,哪些頁面需要緩存頁面等。
虛擬分配頁面的管理過程都是通過一個名為頁幀號(PFN)的列表進行管理的,關於每個物理和虛擬分配頁面的狀態及其相應屬性都有一長串解釋。
本文,我將通過大量實際的案例,來解釋Windows PFN的實現。
如果你熟悉non-PAE模式和PAE模式系統,那麼就應該注意到,在non-PAE模式下,每個PFN結構需要24個位元組,而在PAE模式系統中,需要25個位元組,因此如果你的頁面是4096個位元組,那麼就分配大約24個位元組以保持對每個頁面的追蹤。
在non-PAE模式下,每個物理頁大小是4K,對於每一個物理頁,PFN資料庫會使用一個24位元組長的結構來保存它的相關信息,比如該物理頁是否已經被使用,這是170:1的比率。而在PAE模式下,每個物理頁大小是4K,對於每一個物理頁,PFN資料庫會使用一個28位元組長的結構來保存它的相關信息,這是146:1的比率。這意味著PFN資料庫中,每1G大小的物理內存,都需要大約6M或7M來描述其中的信息。但是如果你有一個具有16G物理內存的32位系統,那麼它只需要大約112M的2G內核虛擬地址空間來處理隨機存取存儲器(RAM)。這也是為什麼擁有16G或更大物理內存的系統不允許使用3G模式(也稱為expaneuserva)的原因,因為該模式會將用戶虛擬地址空間增加到3G並將32位系統的內核虛擬地址空間減少到1G,擴展頁面的好處之一(例如每頁2M)需要更少的MMPFN結構。
在開始深入了解PFN之前,請記住術語「Page」主要用於操作系統級概念,而「Frame」用於CPU級概念,因此「Page」表示虛擬頁面,「Page Frame」表示物理頁面。
PFN列表
PFN由描述某些頁面狀態的列表組成,比如活動列表(Active List)顯示活動頁面(例如,在working sets中);待機列表(Standby List)表示先前在磁碟中備份的列表,頁面本身可以在不產生磁碟IO的情況下清空和重用;修改列表(Modified List )顯示該頁面先前已被修改,並且必須以某種方式寫入磁碟;移出列表(Freed List),顧名思義,它顯示不再需要維護的頁面,可以被移出;最後是零列表(Zero List),描述一個包含全零(0)的頁面。
下圖顯示了PFN資料庫列表之間的相互關聯關係:
這些列表是用於管理內存中「頁面錯誤」狀態的,每次發生「頁面錯誤」後,Windows都試圖找到一個可用的表單頁,如果列表為空則是零列表,然後零列表則從移出列表中獲取可用的表單頁,另外,如果移出列表也為空,則移出列表從待機列表獲取可用的表單頁,並將頁面用全零(0)表示。
零頁面線程
在Windows中,有一個優先順序為0的線程,負責在系統空閑時將內存歸零,並且是整個系統中唯一優先順序為0的線程。這是可用的最低優先順序,因為用戶線程至少是1,該線程儘可能清除移出列表。此外,Windows中有一個名為RtlSecureZeroMemory()的函數,它可以安全地移出一個位置,但是在以下的內核透視圖中,nt!KeZeroPages負責移出頁面。
下圖顯示了零頁面線程的整個過程:
此時,零線程(Zero Thread)就可以看得清清楚楚。知道它來自系統進程,且它的優先順序為0,這應該就足夠了,不再需要更多的信息了。首先嘗試查找系統的nt!_eprocess:
!process 0 System
現在我們可以看到系統的線程,我的目標線程(零線程)的細節如下:
THREAD ffffd4056ed00040 Cid 0004.0040 Teb: 0000000000000000 Win32Thread: 0000000000000000 WAIT: (WrFreePage) KernelMode Non-Alertable fffff8034637f148 NotificationEvent fffff80346380480 NotificationEvent Not impersonating DeviceMap ffff99832ae1b010 Owning Process ffffd4056ec56040 Image: System Attached Process N/A Image: N/A Wait Start TickCount 4910 Ticks: 4 (0:00:00:00.062) Context Switch Count 21023 IdealProcessor: 3 UserTime 00:00:00.000 KernelTime 00:00:01.109 Win32 Start Address nt!MiZeroPageThread (0xfffff80346144ed0) Stack Init ffffe700b7c14c90 Current ffffe700b7c14570 Base ffffe700b7c15000 Limit ffffe700b7c0f000 Call 0000000000000000 Priority 0 BasePriority 0 PriorityDecrement 0 IoPriority 2 PagePriority 5 Child-SP RetAddr Call Site ffffe700`b7c145b0 fffff803`46016f8a nt!KiSwapContext+0x76 ffffe700`b7c146f0 fffff803`46016951 nt!KiSwapThread+0x16a ffffe700`b7c147a0 fffff803`46014ba7 nt!KiCommitThreadWait+0x101 ffffe700`b7c14840 fffff803`461450b7 nt!KeWaitForMultipleObjects+0x217 ffffe700`b7c14920 fffff803`460bba37 nt!MiZeroPageThread+0x1e7 ffffe700`b7c14c10 fffff803`46173456 nt!PspSystemThreadStartup+0x47 ffffe700`b7c14c60 00000000`00000000 nt!KiStartSystemThread+0x16
正如你所看到的,它的起始地址是nt!MiZeroPageThread,且它的優先順序是0,如果你看到調用棧,那麼就可以看到之前調用的 nt!MiZeroPageThread。
更多細節,請訪問《隱藏的內存分配成本》一文。
PFN的Windows結構是nt!_MMPFN,如下圖所示:
如你所見,_MMPFN需要28個位元組。
PFN記錄會根據其物理地址順序存儲在存儲器中,這意味著你可以在PFN的幫助下計算出物理地址。
Physical Address = PFN * page size(e.g 4096 Byte) + offset
PFN資料庫的地址位於nt!MmPfnDatabase,你可以使用以下所示的代碼段在Windbg中獲取PFN資料庫地址。
2: kd> x nt!MmPfnDatabasefffff800`a2a76048 nt!MmPfnDatabase = <no type information>
!memusage
windbg中另一個非常有用的命令是!memusage,這個命令幾乎提供了內存布局中關於PFN和頁面的幾乎所有內容及其相關細節,例如文件、字體、系統驅動程序、DLL模塊、可執行文件(包括它們的名稱和它們的分頁位修改) 。
!memusage命令從物理內存角度顯示內存統計信息,無數個頁面信息將被列印出來,可以說是「最內存」的信息。此命令會查看所有的頁幀,所以運行時會非常的耗時。
該命令的簡要介紹如下所示:
2: kd> !memusage loading PFN databaseloading (100% complete)Compiling memory usage data (99% Complete). Zeroed: 9841 ( 39364 kb) Free: 113298 ( 453192 kb) Standby: 105520 ( 422080 kb) Modified: 7923 ( 31692 kb) ModifiedNoWrite: 0 ( 0 kb) Active/Valid: 286963 ( 1147852 kb) Transition: 45 ( 180 kb) SLIST/Bad: 567 ( 2268 kb) Unknown: 0 ( 0 kb) TOTAL: 524157 ( 2096628 kb)Dangling Yes Commit: 140 ( 560 kb) Dangling No Commit: 37589 ( 150356 kb) Building kernel map Finished building kernel map (Master1 0 for 80) (Master1 0 for 580) (Master1 0 for 800) (Master1 0 for 980)Scanning PFN database - (97% complete) (Master1 0 for 7d100)Scanning PFN database - (100% complete) Usage Summary (in Kb):Control Valid Standby Dirty Shared Locked PageTables nameffffffffd 11288 0 0 0 11288 0 AWEffffd4056ec4c460 0 112 0 0 0 0 mapped_file( LeelUIsl.ttf )ffffd4056ec4c8f0 0 160 0 0 0 0 mapped_file( malgun.ttf )ffffd4056ec4d6b0 0 108 0 0 0 0 mapped_file( framd.ttf ).....ffffd4057034ecd0 328 148 0 0 0 0 mapped_file( usbport.sys )ffffd4057034f0e0 48 28 0 0 0 0 mapped_file( mouclass.sys )ffffd4057034f7d0 32 28 0 0 0 0 mapped_file( serenum.sys )ffffd405703521a0 0 20 0 0 0 0 mapped_file( swenum.sys ).....-------- 0 20 0 ----- ----- 0 session 0 0-------- 4 0 0 ----- ----- 0 session 0 ffffe700b8b45000-------- 4 0 0 ----- ----- 0 session 1 ffffe700b8ead000-------- 32520 0 84 ----- ----- 1324 process ( System ) ffffd4056ec56040-------- 2676 0 0 ----- ----- 304 process ( msdtc.exe ) ffffd405717567c0-------- 4444 0 0 ----- ----- 368 process ( WmiPrvSE.exe ) ffffd405718057c0-------- 37756 0 60 ----- ----- 1028 process ( SearchUI.exe ) ffffd405718e87c0.....-------- 8 0 0 ----- 0 ----- driver ( condrv.sys )-------- 8 0 0 ----- 0 ----- driver ( WdNisDrv.sys )-------- 52 0 0 ----- 0 ----- driver ( peauth.sys )-------- 24744 0 0 ----- 0 ----- ( PFN Database )Summary 1147852 422260 31692 129996 204428 25156 Total..... b45b 64 0 0 60 0 0 Page File Section b56b 4 0 0 4 0 0 Page File Section b7ec 84 0 0 64 0 0 Page File Section b905 12 0 0 0 0 0 Page File Section bf5c 4 0 0 0 0 0 Page File Section .....
有關這些頁面的更多信息,Windbg幫助文檔是這樣解釋的:
你可以使用!vm擴展命令分析虛擬內存使用情況,這個擴展通常比!memusage更有用。有關內存管理的更多信息,請參閱Mark Russinovich和David Solomon撰寫的Microsoft Windows Internals。!pfn擴展命令可用於在PFN資料庫中顯示特定頁幀條目。
在下一節,我會介紹如何更詳細的查看這些命令。
本文翻譯自:https://rayanfam.com/topics/inside-windows-page-frame-nuMer-part1/如若轉載,請註明原文地址: http://www.4hou.com/system/12770.html 更多內容請關注「嘶吼專業版」——Pro4hou
推薦閱讀:
※做開發的如何轉安全?
※深度剖析攻擊目標遍及全世界的組織——Sofacy
※OODA循環在網路安全運營平台建設中的應用
※燕麥云何洋開講丨知道了這些,你還會用共享充電寶嗎?
※如何看待滴滴打車懸賞百萬犯罪嫌疑人個人信息並公布個人身份證號?
TAG:信息安全 |