MDL 詳解 待深入理解

2021-09-10 12:09:45 字數 2473 閱讀 8589

以下的虛擬記憶體可以理解成邏輯記憶體,因為我覺得只有這樣才能講通下面所有的東西。以下的「未分頁」指沒有為頁進行編碼。

的訪問。

·mmge***lvirtualaddress 獲取緩衝區的虛擬記憶體位址

·mmge***lbytecount 獲取緩衝區的大小(位元組數)

·mmge***lbyteoffset 獲取緩衝區開端的物理頁的大小(位元組數)

·mmge***lpfnarray 獲取記錄物理頁碼的乙個陣列指標。

我們可以用ioallocatemdl函式來分配乙個mdl。如果要取消分配,可是使用iofreemdl函式。或者,可以使用mminitializemdl來把乙個之前定義的緩衝區定製成乙個mdl。但是以上兩種方式都不能初始化物理頁碼陣列。

對於在未分頁池中分配的緩衝區,可以用mmbuidlmdlfornonpagedpool函式來初始化頁碼陣列。對於可分頁的記憶體,虛擬記憶體和物理記憶體之間的聯絡是暫時的,所以mdl的頁碼陣列只在特定的環境和時間段有效,因為很可能其他的程式對它們進行重新分配,為了使其他的程式無法對他們進行修改和重新分配(在我們釋放之前),我們就需要把這段記憶體鎖定,防止其他程式修改,我們可以用mmprobeandlockpages來實現,這個函式同時還為當前的布局初始化了頁碼陣列。當我們用mmunlockpages來釋放被鎖定的記憶體時,頁碼陣列也會隨之無效。

假如mdl指定的是對映一塊核心級別的虛擬位址空間,那麼我們要用mmgetsystemaddressformdlsafe ,這樣我們就能防止對映目標是來自使用者模式的空間,而來自使用者模式空間的物理頁只能在使用者模式上下文環境中使用,並且隨時可能被清空。用函式進行申明後,就可以防止以上情況發生了。

以下這個函式是用於新建立乙個mdl的:引數詳解可翻閱msdn

pmdl ioallocatemdl(

in pvoid virtualaddress,

in ulong length,

in boolean secondarybuffer,

in boolean chargequota,

in out pirp irp optional

);最後乙個引數是指irp(輸入輸出請求包),也就是將新建的這個mdl緩衝區和指定的irp關聯,為什麼要關聯?舉個例子,比如網路驅動中就應該為每乙個傳送到本機的ip資料報建立乙個臨時緩衝區,而終端使用者——應用程式要讀取這個緩衝區的資料,必須使用irp請求驅動程式來完成,所以要提取某個ip資料報,只要傳送相關irp給驅動程式,驅動程式遍歷其建立的mdl鏈找到相應的mdl,然後進行資料提取和傳送,請求處理完之後,驅動程式會自動清除這個mdl。乙個irp可以關聯多個mdl,就像上面舉的例子一樣,乙個irp關聯到多個ip資料報(也就是多個mdl)。當應用成語的某個irp要求乙個新的請求(可能是乙個新的ip位址的ip資料報)時,驅動程式發現沒有mdl與之聯,這個時候該ip傳送來乙個ip資料報,這時驅動程式便建立乙個mdl與之關聯,如果這是第乙個新建的與這個irp關聯的mdl,那麼驅動程把該mdl的位址賦值給mdladdress。如果不是第乙個,那麼將把新建的mdl放到上乙個mdl的下乙個單位,形成mdl 鏈。這就是mdl結構體中的第乙個成員的含義所在。

所以要對一塊受系統保護的區域進行寫操作的話,可以這樣來修改它的保護屬性:

1.建立乙個mdl,顯然裡面的物理頁號陣列沒有初始化 ioallocatemdl

2.初始化頁碼陣列,使之成為實際有效的mdl mmbuildmdlfornonpagedpool

3.進行鎖定,並且重新賦值新的保護屬性為可讀 mmprobeandlockpages

4.獲得我們所對映後的實際記憶體區域的虛擬位址 mmmaplockedpagesspecifycache

網上的很多**是用於2000和其之前的os的,很多函式都改了,方式也不一樣了,以下**用於在ssdt表所在的核心區對映乙個mdl,並且修改其唯讀屬性為可寫的,然後固定這塊記憶體,防止它被其他應用程式修改。
g_pmdlsystemcall =ioallocatemdl

(keservicedescriptortable.servicetablebase,keservicedescriptortable.numberofservices*4,false,false,null);

if(!g_pmdlsystemcall)

return status_unsuccessful;

mmprobeandlockpages(g_pmdlsystemcall,kernelmode,iowriteaccess);//在記憶體中鎖定,並且指

明對它的改寫權力

//修改了這個mdl,就是修改了它所描述的記憶體區
g_pmdlsystemcall,

kernelmode,

menoncached,//是否允許用作cpu緩衝區

false,//當第二個引數為usermode的時候才有效

【注意】最後乙個函式其實是大材小用了,只不過2000之後能得到對映緩衝區位址的函式中這個函式是最先進的被支持者,2000用的是mmmaplockedpages;

python 那些待深入理解的東西

class father 2.7版本的老式類 def init self pass def function self print type self print isinstance self,son print isinstance self,father print self.mlist cl...

深入理解C語言 深入理解指標

關於指標,其是c語言的重點,c語言學的好壞,其實就是指標學的好壞。其實指標並不複雜,學習指標,要正確的理解指標。指標也是一種變數,占有記憶體空間,用來儲存記憶體位址 指標就是告訴編譯器,開闢4個位元組的儲存空間 32位系統 無論是幾級指標都是一樣的 p操作記憶體 在指標宣告時,號表示所宣告的變數為指...

mysql 索引深入理解 深入理解MySql的索引

為什麼索引能提高查詢速度 先從 mysql的基本儲存結構說起 mysql的基本儲存結構是頁 記錄都存在頁裡邊 各個資料頁可以組成乙個雙向鍊錶每個資料頁中的記錄又可以組成乙個單向鍊錶 每個資料頁都會為儲存在它裡邊兒的記錄生成乙個頁目錄,在通過主鍵查詢某條記錄的時候可以在頁目錄中使用二分法快速定位到對應...