天天看點

Windows 核心程式設計研究系列之一(-改變程序PTE屬性-)[已補完]

windows 核心程式設計研究系列之一

-改 變 進 程 pte 屬性-

         這是我研究windows 核心程式設計的第一篇正式文章,之是以叫核心程式設計而不叫核心程式設計,是我覺得從字面上來看核心(core)比核心(kernel)更靠近windows中心,當然隻是偶本人的看法的拉。

         我們知道在 win nt 中,系統把每個程序的虛拟4g空間分為兩大部份,低2g歸使用者所有,高2g歸系統所有。使用者不得通路系統的空間,連讀都不行,更别說寫了!低2g的使用者空間也并不是都能寫入的。現在我要說一個特殊的區域:在每個程序虛拟位址 0x7ffe0000 開始的一段空間稱為 user_shared 區域,他和虛拟位址空間0xffdf0000指向同一實體位址空間,這片區域的長度為 0x2d8。是以不同程序的這一虛拟位址空間被映射到同一個實體位址空間,如果可以寫入該區域就可以實作系統中所有程序共享資料的目的,注意是所有程序!但可惜的是雖然0x7ffe0000在低2g的空間,歸使用者所有,但它隻能讀不能寫,寫他的後果如圖1所示。

Windows 核心程式設計研究系列之一(-改變程式PTE屬性-)[已補完]

                                                     圖1

很不爽哦!我前不久在網上看到一篇可以讀寫實體記憶體的文章,其實作的思想是:

1 通過系統特權api取得 system object physicalmemory 的寫權限;

2 通過分析 mmgetphysicaladdress 寫出其在 ring3 下的僞代碼,進而得到任意虛拟位址映射的實際實體位址

3 寫入實體位址

我用彙編重寫後好像不能實作其目的,編譯運作原來vc++代碼也不成功。但據作者說他可以運作成功。因為這篇文章寫得較早,我懷疑是 windows 在後來的pack中關閉了這個通道。但隻是猜測,也不排除還有我未考慮到的因素,希望搞成功過的朋友談談具體的過程。

         我實作的是另一種方法,其主要思想是:

1 找到該虛拟位址在程序頁表中的位置;

2 将對應頁表項第2位改為1

每個程序的頁表被映射到其虛拟位址空間的 0xc0000000 – 0xc003fffff 空間中。經過簡單的計算後得到其頁表項位置為:

0xc0000000 + 0x1fff80 = 0xc01fff80 察看其内容如圖2所示,其最低3位決定了它存在,屬于使用者區域,但是隻讀不能寫入!

Windows 核心程式設計研究系列之一(-改變程式PTE屬性-)[已補完]

                                        圖2

我們下面要做的也非常簡單,就是打開其寫入标志,使其可寫。

就是将 0x25 改為 0x27 。關鍵代碼如下:

mov   ebx,0c01fff80h

     mov   edx,[ebx]

     mov   al,27h

     mov   byte ptr [ebx],al

     mov   eax,cr3

     mov   cr3,eax

通過一個 kernel driver 注入,修改成功。下面就是在ring3中修改 0x7ffe0080的内容,以下是代碼:

mov   ebx,7ffe0080h

     mov   eax,12345678h

     mov   dword ptr [ebx],eax

執行結果可以用任意ring3調試器來證明,就是在調試任意程式時察看其程序位址0x7ffe0080都會發現其值被改為 0x12345678。圖3是驗證情況。

Windows 核心程式設計研究系列之一(-改變程式PTE屬性-)[已補完]

圖3

到這裡貌似可以告一段落了,但是還有更值得挖掘的東西,那就是在ring3種直接改寫高2gb的系統核心區域,下面馬上将給出的是就是關于改寫0x80000000 – 0xffffffff 核心區域的方法,敬請期待。

ok,讓我們進入這一部分,其實有了上面的基礎,這個就變得輕而易舉了。但是要注意的是:

1 要改寫的 0x80000000 – 0xffffffff 區域屬于核心,可能

搞不要就要odbs;

2 要修改的不單單是 pte 還有頁目錄表項

現在我們選擇寫入的位置,上面說過的 0xffdf0000 ~ 0xffdf02d8 是個不錯的選擇,因為除了開頭一段最好别碰以外,後面都是“自由”區域,寫入因該沒什麼問題。我們首先

Windows 核心程式設計研究系列之一(-改變程式PTE屬性-)[已補完]

圖4

要确定修改的頁目錄項的位置,它可以通過 0xc03000000 + 0xffc 算出等于 0xc0300ffc,如圖4,将63改為67。然後再找到

頁表項的位置,通過 0xc0000000 + 0x3ff7c0 = 0xc03ff7c0,同樣的要将63改為67,關鍵代碼為:

mov   ebx,0c0300ffch

     mov   al,67h

     mov   ebx,0c03ff7c0h

that’s all right !!!,讓我們看下實際的效果,如圖5所示。

Windows 核心程式設計研究系列之一(-改變程式PTE屬性-)[已補完]

圖5

繼續閱讀