本文章最後由 SheepKingCN 於 2013-8-25 22:51 編輯
.
此為本人學習、無聊研究用,為了要備份文章,所以才發在這裡。
轉貼文章,我也不忘..改了一些文字語氣,讓文章閱讀起來..通順點XD
作者介紹:
名叫scdeny
是中國大陸人
也是IGS 國際遊戲安全組織的授課老師
作者在網路上的ID:
中國大陸-看雪學院-scdeny
此文章的發布時間:
2011-07-28
------------正文開始------------
先上圖,修補之後的,原來只有2.98G,現在是3.86G了
去年7月入手小黑T410,到手就裝了4G的內存,WINDOWS 7的 補丁來的很快,很順利就用上了3.86G(糾結於剩下的140M哪裡去了?至今也沒搞明白,只知道主板沒有映射),而所謂的XP的種種補丁,不外乎就是Ramdisk,開啟PAE之類的,毫無用處,最可憐的是竟然被某網友的“開啟了PAE就能用到全部4G內存,系統屬性頁顯示還是2.98G是假的”一說給忽悠了一年,中國沒文化真可怕。 。 。就這麼將信將疑用了一年,中間也糾結過一段時間,沒有深入分析,近日越想越感覺不對勁,再來糾結糾結。 。 。
用WinDbg看看- lkd> dd MmHighestPhysicalPage
- 8088b124 000bf7ff 000bf399 00000040 00000000
- lkd> dd MmNumberOfPhysicalPages
- 8088b128 000bf399 00000040 00000000 7fff0000
複製代碼 可見最高物理內存頁號MmHighestPhysicalPage值為bf7ff,物理內存總頁數MmNumberOfPhysicalPages值為bf399,換算成物理內存數0xbf399*0x1000=2.98G正好是系統屬性頁顯示的2.98G,改變這個值,系統屬性頁的值也會跟著變,是不是把這個值改了你就能用到更多的內存了呢,當然不是,任務管理器裡記錄的內存使用量確是真是的。
那是不是我的PAE沒有真正啟用呢?
那我們再用WinDbg看看- lkd> !pte 80800000
- VA 80800000
- PDE at C0602020 PTE at C0404000
- contains 00000000008009E3 contains 0000000000000000
- pfn 800 -GLDA--KWEV LARGE PAGE pfn 800
複製代碼 看吧,PDE和PTE裡面的物理地址00000000008009E3和0000000000000000都是64位的,而在沒有啟用PAE的系統裡,頁表項裡的物理地址是32位的。 (為什麼PTE裡是一串0呢?因為我們看的80800000這個虛擬地址是ntkrnlpa.exe的基地址,它當然是加載在物理內存的0地址的)
那麼是不是系統偷偷地在用我的4G內存了,而給我顯示出2.96G的假象呢?
再祭出我們的法寶WinDbg- lkd> dd poi(MmPhysicalMemoryBlock)
- 8ad75c80 00000007 000bf3ab 00000001 0000009d
- 8ad75c90 00000100 000bf17c 000bf282 000000dd
- 8ad75ca0 000bf40f 00000060 000bf70f 00000008
- 8ad75cb0 000bf71f 0000004c 000bf7ff 00000001
複製代碼 這裡有兩個結構體:- typedef struct _PHYSICAL_MEMORY_RUN {
- PFN_NUMBER BasePage;
- PFN_NUMBER PageCount;
- } PHYSICAL_MEMORY_RUN, *PPHYSICAL_MEMORY_RUN;
- typedef struct _PHYSICAL_MEMORY_DESCRIPTOR {
- ULONG NumberOfRuns;
- PFN_NUMBER NumberOfPages;
- PHYSICAL_MEMORY_RUN Run[1];
- } PHYSICAL_MEMORY_DESCRIPTOR, *PPHYSICAL_MEMORY_DESCRIPTOR;
複製代碼 從上面可以看出,我的機器有7塊可用的內存,總共有bf3ab頁(為什麼這個數字跟上面看到的MmNumberOfPhysicalPages不符呢?),分別為1 -9d,100- bf17c,…,bf7ff,可見最大物理內存地址為bf7ff,還是與4G內存相去甚遠啊。 。 。
那麼是不是我的主板根本就不識別這麼大的內存呢? ?
那麼我們再做做實驗,用nt4的源代碼編譯一份NTLDR,把osloader.exe探測到的物理內存輸出一份,下面是通過中斷獲取的內存佈局圖,BIOS專家們都叫把它做E820圖- Base Size Type
- 0 9E800 1
- 9E800 1800 2
- D2000 2000 2
- DC000 24000 2
- 100000 BF17C000 1
- BF27C000 6000 2
- BF282000 DD000 1
- BF35F000 12000 2
- BF371000 1000 4
- BF3F2000 1D000 2
- BF40F000 60000 1
- BF46F000 1F9000 2
- BF668000 80000 4
- BF6E8000 27000 2
- BF717000 8000 1
- BF71F000 4C000 1
- BF76B000 C000 4
- BF777000 3000 3
- BF77A000 7000 4
- BF781000 1000 3
- BF782000 9000 4
- BF78B000 1000 3
- BF78C000 13000 4
- BF79F000 60000 3
- BF7FF000 1000 1
- BF800000 800000 2
- E0000000 10000000 2
- FEAFF000 1000 2
- FEC00000 10000 2
- FED00000 400 2
- FED1C000 4000 2
- FED20000 70000 2
- FEE00000 1000 2
- FF000000 1000000 2
- 100000000 38000000 1
複製代碼 圖中type為1的就是分配給本機物理內存的地址,其他的為其他硬件所用,我們把內存地址挑出來:- Base Size
- 0 9E800
- 100000 BF17C000
- BF282000 DD000
- BF40F000 60000
- BF717000 8000
- BF71F000 4C000
- BF7FF000 1000
- 100000000 38000000
複製代碼 總數為F73AC800=3.86G,儘管4G以下的地址空間被硬件佔用了不少,主板並沒有放棄那塊內存嘛,只是把他們映射到了4G以上的空間,即100000000-138000000,看來是XP那傢伙太不地道,活生生把咱們使用這塊內存給掐掉了,故而產生了MmHighestPhysicalPage= BF7FF,無恥的傢伙!什麼? XP的內存機制不支持?不要為XP辯解,PAE技術早在Intel P6家族的CPU身上就已經開始使用了,Intel手冊第一卷3.3.6節關於PAE有如下表述:
Beginning with P6 family processors, the IA-32 architecture supports addressing of
up to 64 GBytes (2^36 bytes) of physical memory.
也就是說,從Intel P6家族的CPU開始,(PAE技術讓)IA-32架構的CPU就支持對64G的物理內存進行尋址, P6家族可是很老CPU了,奔二,奔三就屬於P6家族的,所以XP這個後來才發布的操作系統不可能連PAE都沒考慮進去吧。
既然那塊4G以上的內存地址被主板識別,NTLDR也探測到了,操作系統也支持,那我們為什麼還是用不到呢?到底是NTLDR沒有告訴ntkrnlpa.exe,還是ntkrnlpa.exe自己給我們截斷了?
這怎麼調試呢? Bochs?不行,我總共才4G內存,哪有那麼多內存分配給Bochs用呢,要有XP的ntos的源碼就好了,ntos的入口函數為
VOID KiSystemStartup(PLOADER_PARAMETER_BLOCK KissLoaderBlock)
在NTLDR向ntos交權的時候,會將內存描述鍊錶通過結構體參數LOADER_PARAMETER_BLOCK傳過去,這個結構體原型為...- ypedef struct _LOADER_PARAMETER_BLOCK {
- LIST_ENTRY LoadOrderListHead;
- LIST_ENTRY MemoryDescriptorListHead;
- LIST_ENTRY BootDriverListHead;
- ULONG KernelStack;
- ……
- 後面太長,省略掉
- } LOADER_PARAMETER_BLOCK, *PLOADER_PARAMETER_BLOCK;
複製代碼 既然沒有Windows XP的源碼,那就用wrk將就一下吧,將wrk編譯的內核文件wrkx86.exe來替換ntkrnlpa.exe,系統肯定是起不來的,不過我們只需要在wrkx86.exe的入口點打印出NTLDR傳過來的內存描述鍊錶就好了,MEMORY_ALLOCATION_DESCRIPTOR的原型為- typedef struct _MEMORY_ALLOCATION_DESCRIPTOR {
- LIST_ENTRY ListEntry;
- TYPE_OF_MEMORY MemoryType;
- ULONG BasePage;
- ULONG PageCount;
- } MEMORY_ALLOCATION_DESCRIPTOR, *PMEMORY_ALLOCATION_DESCRIPTOR;
複製代碼 於是我們很快得到了結果:
(我無法po圖,真是遺憾...)
咦! NTLDR貌似真的沒有把4G以上的地址傳過來啊,怎麼到FF000這塊內存就完了呢?
難道NTLDR私自把4G以上的地址給裁了?難道一切罪惡的源泉在NTLDR?在此我犯了個嚴重的錯誤,以為勝利在望,加班加點研究NTLDR,最好成功跳過NTLDR截去4G以上內存的代碼了,啟動發現XP依然顯示2.98G的可用內存,怎麼回事呢?回過頭來再分析NTLDR,才發現瞭如下的代碼- if ( (_BYTE)BlUsePae_0 )
- {
- v10 = BlpAllocatePAETables();
- if ( v10 )
- return v10;
- }
- else
- {
- BlpTruncateDescriptors(0xFFFFFu);
- }
複製代碼 BlpTruncateDescriptors(0xFFFFFu)函數的功能就是設置內存描述鍊錶的最大頁面號為0xFFFFF,即截去4G以上的內存,原來我們編譯的wrkx86.exe不支持PAE,被NTLDR發現了,故而才調用BlpTruncateDescriptors截斷的,而我們的XP用的內核ntkrnlpa.exe是支持PAE的,那麼就不會截斷了,哎,馬虎啊。 。 。
那還是鎖定ntkrnlpa.exe分析吧,充分發揚廢寢忘食的精神,終於找到了一個可疑的函數ExVerifySuite,這不會就是驗證我們版本的函數吧,網上一查,發現有位“老生常談”早就發現了,他的文章在這裡
http://thxlp.wordpress.com/2008/ ... ndows%E5%92%8C4g%E4 %BB%A5%E4%B8%8A%E7%89%A9%E7%90%86%E5%86%85%E5%AD%98/
汗。 。 。 。差距啊,不過這位老大發現這麼久竟然不出補丁,拯救我們廣大百姓於水貨,哎。 。 。害我熬夜傷神這麼久。 。 。 。
不過這位“老生”的代碼不知道從哪裡搞的,nt4源碼裡沒有MiCheckPaeLicense這個函數,而windows2000的源代碼裡雖然有這個函數,但差別很大,wrk的源代碼裡也不是那樣的,反彙編XP的ntkrnlpa.exe,代碼如下- int __usercall MiCheckPaeLicense<eax>(PLOADER_PARAMETER_BLOCK LoaderBlock<eax>)
- {
- EndPage = 0;
- LoaderBlock1 = LoaderBlock;
- MaxPageCount = 0x100000u;
- MaxPage = 0;
- if ( ExVerifySuite(DataCenter) == 1 )
- {
- if (LoaderBlock->u.I386.VirtualBias )
- {
- MaxPageCount = 0x400000u; // booting /3gb: 16G
- MaxPage = 0x400000u;
- }
- else
- {
- MaxPageCount = 0x1000000u;
- } // DataCenter: 64G
- }
- else
- {
- if ( MmProductType == 0x690057 || ExVerifySuite(Enterprise) != 1 )
- {
- if ( ExVerifySuite(ServerAppliance) == 1 )
- MaxPageCount = 0x80000u; // 2G
- else
- MaxPage = 0x100000u; // 4G
- }
- else
- {
- MaxPageCount = 0x800000u;// Advanced Server is permitted a maximum of 32gb
- }
- }
複製代碼 我實在是不知道這位高人的代碼來自哪裡,懇請各位高人給予指點。 。 。
從這段代碼裡可以看出,MiCheckPaeLicense函數會檢查操作系統的版本,如果是DataCenter,就允許使用64G內存,Advanced Server為32G,如果為精簡版則為2G,其他版本為4G,看來真是ntkrnlpa .exe在作怪,先別急著patch,驗證內存限制的還有一個地方,在MmAddPhysicalMemoryEx函數里也會調用ExVerifySuite這個函數,代碼如下:- if ( ExVerifySuite(DataCenter) == 1 )
- {
- LimitPage = 0x1000000u; // DataCenter : 64G
- }
- else
- {
- if ( MmProductType == 0x690057 || (v9 = ExVerifySuite(Enterprise) == 1, LimitPage = 0x800000u, !v9) )// Advanced Server : 32G
- LimitPage = 0x100000u; // Other : 4G
- }
複製代碼 代碼都差不多,要patch的話兩個地方要一起改,至於怎麼改?代碼都在這麼裡,想怎麼改就怎麼改吧,只要兩個地方都改了就行,只要其中一個地方不改,ntos都會陰魂不散的把你多出來的內存吃掉…
看成果吧- lkd> dd MmHighestPhysicalPage
- 8088b124 00137fff 000f7399 00000040 00000000
- lkd> dd MmNumberOfPhysicalPages
- 8088b128 000f7399 00000040 00000000 7fff0000
- lkd> !pte d0800000
- VA d0800000
- PDE at C0603420 PTE at C0684000
- contains 00000001004DF963 contains E15C080000000400
- pfn 1004df -G-DA--KWEV not valid
- Proto: E15C0800
複製代碼 數數這個地址1004DF963,9位啊,4GB以上了,不要被E15C080000000400這個地址嚇到了,64位,有這麼大的地址嗎?查查PTE的結構體就知道了,前面的幾位是標誌位
再看物理內存塊- lkd> dd poi(MmPhysicalMemoryBlock)
- 8baa3c70 00000008 000f73ab 00000001 0000009d
- 8baa3c80 00000100 000bf17c 000bf282 000000dd
- 8baa3c90 000bf40f 00000060 000bf70f 00000008
- 8baa3ca0 000bf71f 0000004c 000bf7ff 00000001
- 8baa3cb0 00100000 00038000 0001000a 6c4d6d4d
複製代碼 看到了嗎,我的電腦機器現在有8塊可用的內存了,多了一個100000-138000,總共有f73ab頁了,0xf73ab*0x1000=3.86G,至於還有140M,主板沒映射,用不到了,能不能解決呢?希望各位牛人能夠給予指點。 。 。
後面部分比較倉促,主要是聽到重任到來的消息,沒時間仔細寫了,補丁沒寫完,估計一時半會完成不了了,倉促發帖,開始潛伏。 。 。
忙裡偷閒,補丁寫好了,趕緊傳上來共享,本機測試通過,如果使用過程中發現問題請給我留言。 。 。
——————————————————————————————————————————
最近忙死了,幾天沒上網了,更沒時間去研究這個,讓各位失望了。 。 。壇子裡的牛人們如果有時間去研究研究吧,MengXP執著的鑽研精神讓我佩服,離成功只有一步之遙了,希望大家能齊心協力,早日解決這些問題,我只能忙過這陣子再來了。 。 。
-------------------------------------------------- -------------
實在抱歉,上個版本出的太匆忙了,嚴重問題都沒有發現,下載這個版本XP64G20110805.rar的朋友請罵我,實在是疏忽大意,抱歉抱歉。 。 。 。
已經釋出了 XP64G20111113.rar
-------------------------------------------------- -------------------------------------------------- ------------------------------------------
終於有時間繼續研究一下了,發現原因主要在DMA,修改之後,USB存儲設備基本可以正常使用了,先上補丁,回頭再發技術帖...
注意: 此程式的編碼為簡體中文,如果你的系統是台灣-繁體中文,會顯示亂碼哦! 需要轉換Unicode碼,或者是使用Microsoft AppLocale
XP64G20111113.rar
(17.46 KB, 下載次數: 25)
.
|