初步認識MDL

                    
<h3 style="margin:0px; padding:0px; color:rgb(51,51,51); font-family:Arial; line-height:26px"><a name="t0"></a>
一、</h3>
<p style="color:rgb(51,51,51); font-family:Arial; font-size:14px; line-height:26px">
內存描述符列表 (MDL) 是一個系統定義的結構,通過一系列物理地址描述緩衝區。執行直接 I/O 的驅動程序<span style="color:rgb(204,0,0)">從 I/O 管理器接收一個 MDL 的指針</span>,並通過 MDL 讀寫數據。一些驅動程序在執行直接 I/O 來滿足設備 I/O 控制請求時也使用 MDL。</p>
<p style="color:rgb(51,51,51); font-family:Arial; font-size:14px; line-height:26px">
<span style="color:rgb(255,0,0)">驅動程序編寫人員不應該假設 MDL 描述的內存頁的順序或內容</span>。<span style="color:rgb(255,0,0)">驅動程序不得依賴於 MDL 指向的任何位置的數據值,並且不應該直接取消對內存位置的引用來獲取數據</span>。如果 MDL 描述一個用於直接 I/O 操作的緩衝區,那麼發出 I/O 請求的應用程序可能也<span style="background-color:rgb(255,102,102)">已經</span>將相同內存頁的視圖映射到其地址空間中。如果這樣的話,應用程序和驅動程序可能嘗試同時修改數據,這會導致錯誤。</p>
<p style="color:rgb(51,51,51); font-family:Arial; font-size:14px; line-height:26px">
而且,在一些情況下,MDL 中的位置不會引用內存管理器保留的相同物理頁。當 Microsoft Windows 內存管理器構建一個用於設備讀取的 MDL 時,它<span style="color:rgb(255,102,102)">鎖定傳輸目標使用的物理頁</span>。但是,只由內存管理器來確定保留哪些頁面和丟棄哪些頁面(如果存在的話)。爲什麼內存管理器將數據讀入這些頁,然後丟棄它們?因爲在更大的羣集中進行 I/O 能夠提供更好的性能。</p>
<p style="color:rgb(51,51,51); font-family:Arial; font-size:14px; line-height:26px">
例如,在下圖中,對應於頁 A、Y、Z 和 B 的文件偏移和虛擬地址都是邏輯上相鄰的(雖然物理頁本身不必相鄰)。頁 A 和 B 沒有駐留在內存中,因此內存管理器必須讀取它們。頁 Y 和 Z 已經駐留在內存中,所以不必讀取它們。(事實上,自從最近一次從備份存儲區讀入以來它們可能已經被修改,在這種情況下,覆蓋它們的內容將會發生嚴重錯誤。)但是,在單個操作中讀取頁 A 和 B 比爲頁 A 進行一次讀取併爲頁 B 進行第二次讀取更有效。因此,內存管理器發出一個包含所有 4 個頁(A、Y、Z 和 B)的單個從備份存儲區讀取的請求。這種讀取請求包含對於讀取有意義的任意多頁(依賴於可用內存的量、當前系統使用情況等)。</p>
<p style="color:rgb(51,51,51); font-family:Arial; font-size:14px; line-height:26px">
<img alt="" src="http://img.my.csdn.net/uploads/201209/27/1348740950_9978.jpg" style="border:none; max-width:100%"></p>
<p style="color:rgb(51,51,51); font-family:Arial; font-size:14px; line-height:26px">
當內存管理器構建描述請求的內存描述符列表 (MDL) 時,它提供頁 A 和 B 的有效指針。但是,頁 Y 和 Z 的條目指向單個系統範圍的虛擬頁 X。內存管理器可能會使用來自備份存儲區的潛在的過時數據填充虛擬頁 X(因爲它使得 X 不可見)。但是,如果組件訪問 MDL 中的 Y 和 Z 偏移,那麼它看到的是虛擬頁 X 而不是 Y 和 Z。</p>
<p style="color:rgb(51,51,51); font-family:Arial; font-size:14px; line-height:26px">
內存管理器可以將任何數目的丟棄頁表示爲單個頁,該頁可以在同一個 MDL 中或者甚至多個併發的 MDL(用於不同的驅動程序)中嵌入多次。因此,表示丟棄頁的位置的內容可以隨時都可能改變。</p>
<p style="color:rgb(51,51,51); font-family:Arial; font-size:14px; line-height:26px">
基於 MDL 映射的頁上的數據值來執行解密或計算校驗和的驅動程序不得從系統提供的 MDL 撤銷指針來訪問數據。爲了確保正確的操作,這樣的驅動程序應該根據驅動程序從 I/O 管理器接收到的系統提供的 MDL 來創建一個臨時 MDL。要創建臨時 MDL:</p>
<ol style="color:rgb(51,51,51); font-family:Arial; font-size:14px; line-height:26px">
<li>
<p>調用 <strong>MmGetMdlVirtualAddress</strong> 和 <strong>MmGetMdlByteCount</strong> 來獲取系統提供的 MDL 的虛擬基址和長度。</p>
</li><li>
<p>使用 <em>PoolType</em>=<strong>NonPagedPool</strong> 調用 <strong>ExAllocatePoolWithTag</strong> 來從未分頁內存池分配緩衝區。指定等於系統提供的 MDL 長度的緩衝區大小,向上擴大到頁邊界。</p>
</li><li>
<p>調用 <strong>IoAllocateMdl</strong> 來分配一個 MDL(使用步驟 2 中創建的池緩衝區的虛擬基址和長度)。</p>
</li><li>
<p>調用 <strong>MmBuildMdlForNonpagedPool</strong> 來更新臨時 MDL,使其描述步驟 2 中池緩衝區的底層物理頁)。</p>
</li></ol>
<p style="color:rgb(51,51,51); font-family:Arial; font-size:14px; line-height:26px">
驅動程序應該將這個臨時 MDL 傳遞給從其硬件讀取數據的調用,然後在任何需要的操作中使用臨時 MDL 描述的數據值。通過調用 <strong>MmBuildMdlForNonPagedPool</strong> 來更新臨時 MDL,驅動程序可以確保臨時 MDL 不包含任何臨時頁,這樣可以使其不會發生對頁內容的任何改變。通過這種方式,即使系統 MDL 包含將被丟棄的(可能重複的)頁,驅動程序仍然可以避免檢查不穩定的內容。當驅動程序完成其操作時,它應該通過在<strong>try/except</strong> 或<strong>try/finally</strong> 塊中使用 <strong>RtlCopyMemory</strong> 將更改的數據從臨時
 MDL 複製回系統提供的 MDL。</p>
<p style="color:rgb(51,51,51); font-family:Arial; font-size:14px; line-height:26px">
使用 MDL 作爲典型 I/O 操作的一部分的驅動程序(不訪問底層頁上的數據)不需要創建臨時 MDL。在內部實現上,內存管理器跟蹤駐留的所有頁以及每個頁如何被映射。當驅動程序將 MDL 傳遞給系統服務例程來執行 I/O 時,內存管理器確保使用正確的數據。</p>
<h4 style="margin:0px; padding:0px; color:rgb(51,51,51); font-family:Arial; font-size:14px; line-height:26px">
<a target="_blank" name="t1" style="color:rgb(51,102,153)"></a><a target="_blank" name="t1" style="color:rgb(51,102,153)"></a><a target="_blank" class="       " name="t1" style="color:rgb(51,102,153)"></a>您應該做什麼?</h4>
<ul style="color:rgb(51,51,51); font-family:Arial; font-size:14px; line-height:26px">
<li>
<p>不要假設 MDL 指向的任何內存位置的內容在任何給定的時間都有效。</p>
</li><li>
<p>如果您的驅動程序依賴於數據的值,那麼始終應該在系統提供的 MDL 中雙重緩存數據。</p>
</li></ul>
<p style="color:rgb(51,51,51); font-family:Arial; font-size:14px; line-height:26px">
 </p>
<p style="color:rgb(51,51,51); font-family:Arial; font-size:14px; line-height:26px">
 </p>
<p style="color:rgb(51,51,51); font-family:Arial; font-size:14px; line-height:26px">
 </p>
<p style="color:rgb(51,51,51); font-family:Arial; font-size:14px; line-height:26px">
二、</p>
<p style="color:rgb(51,51,51); font-family:Arial; font-size:14px; line-height:26px">
前段時間在羣裏有人問起什麼是MDL,當時三言兩語也不知道解釋清楚了沒,今天閒着無事,索性記錄下來吧,就當是做個筆記,以後忘了也好查閱。</p>
<p style="color:rgb(51,51,51); font-family:Arial; font-size:14px; line-height:26px">
我們知道,系統中一些重要的表項如<span style="color:rgb(255,0,0)">SSDT是隻讀的</span>,如果我們強行對其進行修改就會造成BSOD的嚴重後果。當然這種保護方式很容易被繞過,我們曾經介紹了通過<span style="background-color:rgb(255,204,204)">修改cr0來禁用WP(Write Protect,寫保護)位</span>的方法,現在再介紹一種不需要使用匯編的方法,就是MDL。</p>
<p style="color:rgb(51,51,51); font-family:Arial; font-size:14px; line-height:26px">
MDL的全稱是<span style="color:rgb(255,153,0)">Memory Descriptor List</span>,即內存描述符表。我們可以通過MDL描述一塊內存區域,在MDL中包含了<span style="color:rgb(255,102,102)">該內存區域的起始地址、擁有者進程、字節數量、標記等信息</span>,如下所示:<br>
</p>
<div class="dp-highlighter bg_java" style="font-family:Consolas,'Courier New',Courier,mono,serif; width:700.906px; overflow:auto; padding-top:1px; color:rgb(51,51,51); line-height:26px; margin:18px 0px!important; background-color:rgb(231,229,220)">
<div class="bar" style="padding-left:45px">
<div class="tools" style="padding:3px 8px 10px 10px; font-size:9px; line-height:normal; font-family:Verdana,Geneva,Arial,Helvetica,sans-serif; color:silver; border-left-width:3px; border-left-style:solid; border-left-color:rgb(108,226,108); background-color:rgb(248,248,248)">
<strong>[java]</strong> <a target="_blank" href="http://blog.csdn.net/chenyujing1234/article/details/8025968#" class="ViewSource" title="view plain" style="color:rgb(160,160,160); text-decoration:none; border:none; padding:1px; margin:0px 10px 0px 0px; font-size:9px; display:inline-block; width:16px; height:16px; text-indent:-2000px; background-color:inherit">view
 plain</a><a target="_blank" href="http://blog.csdn.net/chenyujing1234/article/details/8025968#" class="CopyToClipboard" title="copy" style="color:rgb(160,160,160); text-decoration:none; border:none; padding:1px; margin:0px 10px 0px 0px; font-size:9px; display:inline-block; width:16px; height:16px; text-indent:-2000px; background-color:inherit">copy</a>
<div style="position:absolute; left:516px; top:2475px; width:18px; height:18px; z-index:99">
</div>
<div style="position: absolute; left: 251px; top: 2075px; width: 16px; height: 16px; z-index: 99;"><embed id="ZeroClipboardMovie_1" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="16" height="16" name="ZeroClipboardMovie_1" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=1&width=16&height=16" wmode="transparent"></div></div>
</div>
<ol class="dp-j" start="1" style="padding:0px; border:none; color:rgb(92,92,92); margin:0px 0px 1px 45px!important; background-color:rgb(255,255,255)">
<li class="alt" style="border-style:none none none solid; border-left-width:3px; border-left-color:rgb(108,226,108); list-style:decimal-leading-zero outside; color:inherit; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important">
<span style="margin:0px; padding:0px; border:none; color:black; background-color:inherit"><span style="margin:0px; padding:0px; border:none; background-color:inherit">typedef struct _MDL   </span></span></li><li style="border-style:none none none solid; border-left-width:3px; border-left-color:rgb(108,226,108); list-style:decimal-leading-zero outside; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important; background-color:rgb(248,248,248)">
<span style="margin:0px; padding:0px; border:none; color:black; background-color:inherit">{  </span></li><li class="alt" style="border-style:none none none solid; border-left-width:3px; border-left-color:rgb(108,226,108); list-style:decimal-leading-zero outside; color:inherit; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important">
<span style="margin:0px; padding:0px; border:none; color:black; background-color:inherit">    struct _MDL     *Next;  </span></li><li style="border-style:none none none solid; border-left-width:3px; border-left-color:rgb(108,226,108); list-style:decimal-leading-zero outside; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important; background-color:rgb(248,248,248)">
<span style="margin:0px; padding:0px; border:none; color:black; background-color:inherit">    CSHORT          Size;  </span></li><li class="alt" style="border-style:none none none solid; border-left-width:3px; border-left-color:rgb(108,226,108); list-style:decimal-leading-zero outside; color:inherit; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important">
<span style="margin:0px; padding:0px; border:none; color:black; background-color:inherit">    CSHORT          MdlFlags;  </span></li><li style="border-style:none none none solid; border-left-width:3px; border-left-color:rgb(108,226,108); list-style:decimal-leading-zero outside; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important; background-color:rgb(248,248,248)">
<span style="margin:0px; padding:0px; border:none; color:black; background-color:inherit">    struct _EPROCESS *Process;  </span></li><li class="alt" style="border-style:none none none solid; border-left-width:3px; border-left-color:rgb(108,226,108); list-style:decimal-leading-zero outside; color:inherit; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important">
<span style="margin:0px; padding:0px; border:none; color:black; background-color:inherit">    PVOID           MappedSystemVa;  </span></li><li style="border-style:none none none solid; border-left-width:3px; border-left-color:rgb(108,226,108); list-style:decimal-leading-zero outside; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important; background-color:rgb(248,248,248)">
<span style="margin:0px; padding:0px; border:none; color:black; background-color:inherit">    PVOID           StartVa;  </span></li><li class="alt" style="border-style:none none none solid; border-left-width:3px; border-left-color:rgb(108,226,108); list-style:decimal-leading-zero outside; color:inherit; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important">
<span style="margin:0px; padding:0px; border:none; color:black; background-color:inherit">    ULONG           ByteCount;  </span></li><li style="border-style:none none none solid; border-left-width:3px; border-left-color:rgb(108,226,108); list-style:decimal-leading-zero outside; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important; background-color:rgb(248,248,248)">
<span style="margin:0px; padding:0px; border:none; color:black; background-color:inherit">    ULONG           ByteOffset;  </span></li><li class="alt" style="border-style:none none none solid; border-left-width:3px; border-left-color:rgb(108,226,108); list-style:decimal-leading-zero outside; color:inherit; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important">
<span style="margin:0px; padding:0px; border:none; color:black; background-color:inherit">} MDL, *PMDL;  </span></li></ol>
</div>
<p style="color:rgb(51,51,51); font-family:Arial; font-size:14px; line-height:26px">
<br>
我們先來看一段在SSDT HOOK中常見的代碼,如下所示:<br>
</p>
<div class="dp-highlighter bg_cpp" style="font-family:Consolas,'Courier New',Courier,mono,serif; width:700.906px; overflow:auto; padding-top:1px; color:rgb(51,51,51); line-height:26px; margin:18px 0px!important; background-color:rgb(231,229,220)">
<div class="bar" style="padding-left:45px">
<div class="tools" style="padding:3px 8px 10px 10px; font-size:9px; line-height:normal; font-family:Verdana,Geneva,Arial,Helvetica,sans-serif; color:silver; border-left-width:3px; border-left-style:solid; border-left-color:rgb(108,226,108); background-color:rgb(248,248,248)">
<strong>[cpp]</strong> <a target="_blank" href="http://blog.csdn.net/chenyujing1234/article/details/8025968#" class="ViewSource" title="view plain" style="color:rgb(160,160,160); text-decoration:none; border:none; padding:1px; margin:0px 10px 0px 0px; font-size:9px; display:inline-block; width:16px; height:16px; text-indent:-2000px; background-color:inherit">view
 plain</a><a target="_blank" href="http://blog.csdn.net/chenyujing1234/article/details/8025968#" class="CopyToClipboard" title="copy" style="color:rgb(160,160,160); text-decoration:none; border:none; padding:1px; margin:0px 10px 0px 0px; font-size:9px; display:inline-block; width:16px; height:16px; text-indent:-2000px; background-color:inherit">copy</a>
<div style="position:absolute; left:510px; top:2794px; width:18px; height:18px; z-index:99">
</div>
<div style="position: absolute; left: 245px; top: 2392px; width: 16px; height: 16px; z-index: 99;"><embed id="ZeroClipboardMovie_2" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="16" height="16" name="ZeroClipboardMovie_2" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=2&width=16&height=16" wmode="transparent"></div></div>
</div>
<ol class="dp-cpp" start="1" style="padding:0px; border:none; color:rgb(92,92,92); margin:0px 0px 1px 45px!important; background-color:rgb(255,255,255)">
<li class="alt" style="border-style:none none none solid; border-left-width:3px; border-left-color:rgb(108,226,108); list-style:decimal-leading-zero outside; color:inherit; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important">
<span style="margin:0px; padding:0px; border:none; color:black; background-color:inherit"><span style="margin:0px; padding:0px; border:none; background-color:inherit">PMDL MDSystemCall;  </span></span></li><li style="border-style:none none none solid; border-left-width:3px; border-left-color:rgb(108,226,108); list-style:decimal-leading-zero outside; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important; background-color:rgb(248,248,248)">
<span style="margin:0px; padding:0px; border:none; color:black; background-color:inherit"><span class="datatypes" style="margin:0px; padding:0px; border:none; color:rgb(46,139,87); font-weight:bold; background-color:inherit">PVOID</span><span style="margin:0px; padding:0px; border:none; background-color:inherit"> *MappedSCT;  </span></span></li><li class="alt" style="border-style:none none none solid; border-left-width:3px; border-left-color:rgb(108,226,108); list-style:decimal-leading-zero outside; color:inherit; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important">
<span style="margin:0px; padding:0px; border:none; color:black; background-color:inherit">  </span></li><li style="border-style:none none none solid; border-left-width:3px; border-left-color:rgb(108,226,108); list-style:decimal-leading-zero outside; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important; background-color:rgb(248,248,248)">
<span style="margin:0px; padding:0px; border:none; color:black; background-color:inherit">MDSystemCall = MmCreateMdl(NULL, KeServiceDescriptorTable.ServiceTableBase, KeServiceDescriptorTable.NumberOfServices*4);  </span></li><li class="alt" style="border-style:none none none solid; border-left-width:3px; border-left-color:rgb(108,226,108); list-style:decimal-leading-zero outside; color:inherit; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important">
<span style="margin:0px; padding:0px; border:none; color:black; background-color:inherit"><span class="keyword" style="margin:0px; padding:0px; border:none; color:rgb(0,102,153); font-weight:bold; background-color:inherit">if</span><span style="margin:0px; padding:0px; border:none; background-color:inherit">(!MDSystemCall)  </span></span></li><li style="border-style:none none none solid; border-left-width:3px; border-left-color:rgb(108,226,108); list-style:decimal-leading-zero outside; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important; background-color:rgb(248,248,248)">
<span style="margin:0px; padding:0px; border:none; color:black; background-color:inherit">{  </span></li><li class="alt" style="border-style:none none none solid; border-left-width:3px; border-left-color:rgb(108,226,108); list-style:decimal-leading-zero outside; color:inherit; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important">
<span style="margin:0px; padding:0px; border:none; color:black; background-color:inherit">    <span class="keyword" style="margin:0px; padding:0px; border:none; color:rgb(0,102,153); font-weight:bold; background-color:inherit">return</span><span style="margin:0px; padding:0px; border:none; background-color:inherit"> STATUS_UNSUCCESSFUL;  </span></span></li><li style="border-style:none none none solid; border-left-width:3px; border-left-color:rgb(108,226,108); list-style:decimal-leading-zero outside; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important; background-color:rgb(248,248,248)">
<span style="margin:0px; padding:0px; border:none; color:black; background-color:inherit">}  </span></li><li class="alt" style="border-style:none none none solid; border-left-width:3px; border-left-color:rgb(108,226,108); list-style:decimal-leading-zero outside; color:inherit; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important">
<span style="margin:0px; padding:0px; border:none; color:black; background-color:inherit">MmBuildMdlForNonPagedPool(MDSystemCall);  </span></li><li style="border-style:none none none solid; border-left-width:3px; border-left-color:rgb(108,226,108); list-style:decimal-leading-zero outside; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important; background-color:rgb(248,248,248)">
<span style="margin:0px; padding:0px; border:none; color:black; background-color:inherit">MDSystemCall->MdlFlags |= MDL_MAPPED_TO_SYSTEM_VA;  </span></li><li class="alt" style="border-style:none none none solid; border-left-width:3px; border-left-color:rgb(108,226,108); list-style:decimal-leading-zero outside; color:inherit; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important">
<span style="margin:0px; padding:0px; border:none; color:black; background-color:inherit">MappedSCT = MmMapLockedPages(MDSystemCall, KernelMode);  </span></li><li style="border-style:none none none solid; border-left-width:3px; border-left-color:rgb(108,226,108); list-style:decimal-leading-zero outside; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important; background-color:rgb(248,248,248)">
<span style="margin:0px; padding:0px; border:none; color:black; background-color:inherit">HookOn( ZwTerminateProcess, New_ZwTerminateProcess);  </span></li></ol>
</div>
<p style="color:rgb(51,51,51); font-family:Arial; font-size:14px; line-height:26px">
其中<span style="color:rgb(255,102,102)">KeServiceDescriptorTable描述的是SSDT,其中ServiceTableBase標明瞭SSDT的起始地址</span>,因此我們通過MmCreateMdl函數創建一個MDL,它剛好把SSDT這塊內存包含在內,有人可能會問,它的長度爲啥是“KeServiceDescriptorTable.NumberOfServices*4”字節呢?很簡單,因爲<span style="color:rgb(255,0,0)">指針的長度是4個字節</span>。</p>
<p style="color:rgb(51,51,51); font-family:Arial; font-size:14px; line-height:26px">
後面的代碼首先<span style="color:rgb(255,102,102)">從不分頁的內存池中Build MDL</span>,然後添加一個MDL_MAPPED_TO_SYSTEM_VA標記以便允許寫入該內存區域;</p>
<p style="color:rgb(51,51,51); font-family:Arial; font-size:14px; line-height:26px">
然後我們將這塊內存鎖起來,現在可以就開始HOOK SSDT了,直到關閉HOOK後纔將其釋放。從這裏就可以看出,這種方式明顯沒有修改cr0的方法好,呵呵呵呵。</p>
<p style="color:rgb(51,51,51); font-family:Arial; font-size:14px; line-height:26px">
不過這種方法的應用範圍比較廣,控制精度也較好,精確地指定了要修改哪一塊內存的標記,兩者方法算是各有千秋吧,誰喜歡用哪一種都可以。</p>
<p style="color:rgb(51,51,51); font-family:Arial; font-size:14px; line-height:26px">
<br>
 三、</p>
<p style="color:rgb(51,51,51); font-family:Arial; font-size:14px; line-height:26px">
<a target="_blank" href="http://www.cnblogs.com/guanlaiy/archive/2012/09/06/2673375.html" style="color:rgb(51,102,153); text-decoration:none">http://www.cnblogs.com/guanlaiy/archive/2012/09/06/2673375.html</a></p>
<p style="color:rgb(51,51,51); font-family:Arial; font-size:14px; line-height:26px">
一 MDL是什麼 </p>
<p style="color:rgb(51,51,51); font-family:Arial; font-size:14px; line-height:26px">
在MSDN中有這樣的定義</p>
<p style="color:rgb(51,51,51); font-family:Arial; font-size:14px; line-height:26px">
內存描述符列表 (MDL) 是一個系統定義的結構,通過一系列物理地址描述緩衝區。執行直接 I/O 的驅動程序從 I/O 管理器接收一個 MDL 的指針,並通過 MDL 讀寫數據。一些驅動程序在執行直接 I/O 來滿足設備 I/O 控制請求時也使用 MDL。</p>
<p style="color:rgb(51,51,51); font-family:Arial; font-size:14px; line-height:26px">
<a target="_blank" href="http://msdn.microsoft.com/zh-cn/windows/hardware/gg463193.aspx" style="color:rgb(51,102,153); text-decoration:none">http://msdn.microsoft.com/zh-cn/windows/hardware/gg463193.aspx</a>這裏有完整的內容,但該文章是機器人翻譯過來的,所以看起來有點頭疼.</p>
<p style="color:rgb(51,51,51); font-family:Arial; font-size:14px; line-height:26px">
因此通俗的解釋一下,MDL僅僅運用於內核中,在應用層並不會涉及這個結構,由於內核中的驅動有跟應用層程序通信的需要,因此可能會接收到來自進程空間的虛擬地址,而在windows的分頁機制下,進程空間中的任何一個虛擬地址所屬的頁面都有可能被內存管理器從RAW置換到頁文件中,或者,進程被釋放或是取消地址的映射。這些都會導致嚴重的錯誤發生。因此內核創建一個MDL,並將其與來自進程空間的虛擬地址相關聯,當需要對這些虛擬地址進行讀寫的時候調用相關的內核函數,鎖定這些虛擬地址對應的物理頁面和邏輯頁面,防止物理頁面被置換,邏輯頁面被修改或者釋放。</p>
<p style="color:rgb(51,51,51); font-family:Arial; font-size:14px; line-height:26px">
另外一種情況下一個驅動程序在執行純內核任務中也可以使用MDL,特別的僅僅調用非分頁內存的話,這些頁面是不會置換到頁文件中的,因此不需要考慮鎖定頁面的問題。</p>
<h3 style="margin:0px; padding:0px; color:rgb(51,51,51); font-family:Arial; line-height:26px"><a name="t1"></a>
<a target="_blank" name="t2" style="color:rgb(51,102,153)"></a><a target="_blank" name="t2" style="color:rgb(51,102,153)"></a>二 MDL的內容</h3>
<p style="color:rgb(51,51,51); font-family:Arial; font-size:14px; line-height:26px">
先看看wdm.h中MDL的定義:</p>
<div class="dp-highlighter bg_cpp" style="font-family:Consolas,'Courier New',Courier,mono,serif; width:700.906px; overflow:auto; padding-top:1px; color:rgb(51,51,51); line-height:26px; margin:18px 0px!important; background-color:rgb(231,229,220)">
<div class="bar" style="padding-left:45px">
<div class="tools" style="padding:3px 8px 10px 10px; font-size:9px; line-height:normal; font-family:Verdana,Geneva,Arial,Helvetica,sans-serif; color:silver; border-left-width:3px; border-left-style:solid; border-left-color:rgb(108,226,108); background-color:rgb(248,248,248)">
<strong>[cpp]</strong> <a target="_blank" href="http://blog.csdn.net/chenyujing1234/article/details/8025968#" class="ViewSource" title="view plain" style="color:rgb(160,160,160); text-decoration:none; border:none; padding:1px; margin:0px 10px 0px 0px; font-size:9px; display:inline-block; width:16px; height:16px; text-indent:-2000px; background-color:inherit">view
 plain</a><a target="_blank" href="http://blog.csdn.net/chenyujing1234/article/details/8025968#" class="CopyToClipboard" title="copy" style="color:rgb(160,160,160); text-decoration:none; border:none; padding:1px; margin:0px 10px 0px 0px; font-size:9px; display:inline-block; width:16px; height:16px; text-indent:-2000px; background-color:inherit">copy</a>
<div style="position:absolute; left:510px; top:4032px; width:18px; height:18px; z-index:99">
</div>
<div style="position: absolute; left: 245px; top: 3534px; width: 16px; height: 16px; z-index: 99;"><embed id="ZeroClipboardMovie_3" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="16" height="16" name="ZeroClipboardMovie_3" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=3&width=16&height=16" wmode="transparent"></div></div>
</div>
<ol class="dp-cpp" start="1" style="padding:0px; border:none; color:rgb(92,92,92); margin:0px 0px 1px 45px!important; background-color:rgb(255,255,255)">
<li class="alt" style="border-style:none none none solid; border-left-width:3px; border-left-color:rgb(108,226,108); list-style:decimal-leading-zero outside; color:inherit; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important">
<span style="margin:0px; padding:0px; border:none; color:black; background-color:inherit"><span class="keyword" style="margin:0px; padding:0px; border:none; color:rgb(0,102,153); font-weight:bold; background-color:inherit">typedef</span><span style="margin:0px; padding:0px; border:none; background-color:inherit"> __struct_bcount(Size) </span><span class="keyword" style="margin:0px; padding:0px; border:none; color:rgb(0,102,153); font-weight:bold; background-color:inherit">struct</span><span style="margin:0px; padding:0px; border:none; background-color:inherit"> _MDL {  </span></span></li><li style="border-style:none none none solid; border-left-width:3px; border-left-color:rgb(108,226,108); list-style:decimal-leading-zero outside; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important; background-color:rgb(248,248,248)">
<span style="margin:0px; padding:0px; border:none; color:black; background-color:inherit">    <span class="keyword" style="margin:0px; padding:0px; border:none; color:rgb(0,102,153); font-weight:bold; background-color:inherit">struct</span><span style="margin:0px; padding:0px; border:none; background-color:inherit"> _MDL *Next;  </span></span></li><li class="alt" style="border-style:none none none solid; border-left-width:3px; border-left-color:rgb(108,226,108); list-style:decimal-leading-zero outside; color:inherit; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important">
<span style="margin:0px; padding:0px; border:none; color:black; background-color:inherit">    CSHORT Size;  </span></li><li style="border-style:none none none solid; border-left-width:3px; border-left-color:rgb(108,226,108); list-style:decimal-leading-zero outside; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important; background-color:rgb(248,248,248)">
<span style="margin:0px; padding:0px; border:none; color:black; background-color:inherit">    CSHORT MdlFlags;  </span></li><li class="alt" style="border-style:none none none solid; border-left-width:3px; border-left-color:rgb(108,226,108); list-style:decimal-leading-zero outside; color:inherit; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important">
<span style="margin:0px; padding:0px; border:none; color:black; background-color:inherit">    <span class="keyword" style="margin:0px; padding:0px; border:none; color:rgb(0,102,153); font-weight:bold; background-color:inherit">struct</span><span style="margin:0px; padding:0px; border:none; background-color:inherit"> _EPROCESS *Process;  </span></span></li><li style="border-style:none none none solid; border-left-width:3px; border-left-color:rgb(108,226,108); list-style:decimal-leading-zero outside; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important; background-color:rgb(248,248,248)">
<span style="margin:0px; padding:0px; border:none; color:black; background-color:inherit">    <span class="datatypes" style="margin:0px; padding:0px; border:none; color:rgb(46,139,87); font-weight:bold; background-color:inherit">PVOID</span><span style="margin:0px; padding:0px; border:none; background-color:inherit"> MappedSystemVa;  </span></span></li><li class="alt" style="border-style:none none none solid; border-left-width:3px; border-left-color:rgb(108,226,108); list-style:decimal-leading-zero outside; color:inherit; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important">
<span style="margin:0px; padding:0px; border:none; color:black; background-color:inherit">    <span class="datatypes" style="margin:0px; padding:0px; border:none; color:rgb(46,139,87); font-weight:bold; background-color:inherit">PVOID</span><span style="margin:0px; padding:0px; border:none; background-color:inherit"> StartVa;  </span></span></li><li style="border-style:none none none solid; border-left-width:3px; border-left-color:rgb(108,226,108); list-style:decimal-leading-zero outside; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important; background-color:rgb(248,248,248)">
<span style="margin:0px; padding:0px; border:none; color:black; background-color:inherit">    <span class="datatypes" style="margin:0px; padding:0px; border:none; color:rgb(46,139,87); font-weight:bold; background-color:inherit">ULONG</span><span style="margin:0px; padding:0px; border:none; background-color:inherit"> ByteCount;  </span></span></li><li class="alt" style="border-style:none none none solid; border-left-width:3px; border-left-color:rgb(108,226,108); list-style:decimal-leading-zero outside; color:inherit; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important">
<span style="margin:0px; padding:0px; border:none; color:black; background-color:inherit">    <span class="datatypes" style="margin:0px; padding:0px; border:none; color:rgb(46,139,87); font-weight:bold; background-color:inherit">ULONG</span><span style="margin:0px; padding:0px; border:none; background-color:inherit"> ByteOffset;  </span></span></li><li style="border-style:none none none solid; border-left-width:3px; border-left-color:rgb(108,226,108); list-style:decimal-leading-zero outside; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important; background-color:rgb(248,248,248)">
<span style="margin:0px; padding:0px; border:none; color:black; background-color:inherit">} MDL, *PMDL;  </span></li></ol>
</div>
<p style="color:rgb(51,51,51); font-family:Arial; font-size:14px; line-height:26px">
<br>
 </p>
<p style="color:rgb(51,51,51); font-family:Arial; font-size:14px; line-height:26px">
先大概說明一下愛各個字段:</p>
<p style="color:rgb(51,51,51); font-family:Arial; font-size:14px; line-height:26px">
   Next:MDL可以連接成一個單鏈表,因此可以將分散的虛擬機地址串接起來。</p>
<p style="color:rgb(51,51,51); font-family:Arial; font-size:14px; line-height:26px">
    Size:一個MDL並不單單包含結構裏這些東西,在內存中緊接着一個MDL結構,存着這個MDL對應的各個物理頁面編號,由於一個物理頁面一定是4KB對齊的,所以這個編號相當於一個物理頁面起始地址的高20位。Size的值減去sizeof(MDL),等於存放編號的區域的大小。比如該MDL需要三個物理頁面來映射虛擬地址空間,則Size-sizeof(MDL)==4*3==12;</p>
<p style="color:rgb(51,51,51); font-family:Arial; font-size:14px; line-height:26px">
    MdlFlags:很重要的字段,用於描述和操控虛擬地址的各種屬性。</p>
<p style="color:rgb(51,51,51); font-family:Arial; font-size:14px; line-height:26px">
    Process:如果虛擬地址是某一進程的用戶地址空間,那麼MDL代表的這塊虛擬地址必須是從屬於某一個進程,這個成員指向從屬進程的結構</p>
<p style="color:rgb(51,51,51); font-family:Arial; font-size:14px; line-height:26px">
    MappedSystemVa:該MDL結構對應的物理頁面可能被映射到內核地址空間,這個成員代表這個內核地址空間下的虛擬地址。對MmBuildMdlForNonPagedPool的逆向表明,MappedSystemVa=StartVa+ByteOffset。這是因爲這個函數的輸入MDL,其StartVa是由ExAllocatePoolWithTag決定的,所以已經從內核空間到物理頁面建立了映射,MappedSystemVa自然就可以這樣算。 可以猜測,如果是調用<strong>MmProbeAndLockPages</strong> 返回,則MappedSystemVa不會與StartVa有這樣的對應關係,因爲此時對應的物理頁面還沒有被映射到內核空間。(此處未定,<strong>MmProbeAndLockPages</strong> 是否會到PDE與PTE中建立映射,未知。)</p>
<p style="color:rgb(51,51,51); font-family:Arial; font-size:14px; line-height:26px">
    StartVa:虛擬地址空間的首地址,當這塊虛擬地址描述的是一個用戶進程地址空間的一塊時,這個地址從屬於某一個進程。</p>
<p style="color:rgb(51,51,51); font-family:Arial; font-size:14px; line-height:26px">
    ByteCount:虛擬地址塊的大小,字節數</p>
<p style="color:rgb(51,51,51); font-family:Arial; font-size:14px; line-height:26px">
    ByteOffset:StartVa+ByteCount等於緩衝區的開始地址</p>
<p style="color:rgb(51,51,51); font-family:Arial; font-size:14px; line-height:26px">
<br>
 由於WDK文檔中表述得比較模糊,上面的說明有些僅僅是猜測。我們可以通過DBG調試一個驅動,觀察它的內存原始數據來證實我們的推測。</p>
<p style="color:rgb(51,51,51); font-family:Arial; font-size:14px; line-height:26px">
下面是取自tdifw中的一段代碼,它爲一個IPV4地址ctx->tai 分配一個非分頁內存塊,然後調用IoAllocateMdl創建一個針對這個虛擬地址的MDL,最後調用MmBuildMdlForNonPagedPool來建立虛擬地址與物理頁面直接的映射。</p>
<div class="dp-highlighter bg_cpp" style="font-family:Consolas,'Courier New',Courier,mono,serif; width:700.906px; overflow:auto; padding-top:1px; color:rgb(51,51,51); line-height:26px; margin:18px 0px!important; background-color:rgb(231,229,220)">
<div class="bar" style="padding-left:45px">
<div class="tools" style="padding:3px 8px 10px 10px; font-size:9px; line-height:normal; font-family:Verdana,Geneva,Arial,Helvetica,sans-serif; color:silver; border-left-width:3px; border-left-style:solid; border-left-color:rgb(108,226,108); background-color:rgb(248,248,248)">
<strong>[cpp]</strong> <a target="_blank" href="http://blog.csdn.net/chenyujing1234/article/details/8025968#" class="ViewSource" title="view plain" style="color:rgb(160,160,160); text-decoration:none; border:none; padding:1px; margin:0px 10px 0px 0px; font-size:9px; display:inline-block; width:16px; height:16px; text-indent:-2000px; background-color:inherit">view
 plain</a><a target="_blank" href="http://blog.csdn.net/chenyujing1234/article/details/8025968#" class="CopyToClipboard" title="copy" style="color:rgb(160,160,160); text-decoration:none; border:none; padding:1px; margin:0px 10px 0px 0px; font-size:9px; display:inline-block; width:16px; height:16px; text-indent:-2000px; background-color:inherit">copy</a>
<div style="position:absolute; left:510px; top:5111px; width:18px; height:18px; z-index:99">
</div>
<div style="position: absolute; left: 245px; top: 4555px; width: 16px; height: 16px; z-index: 99;"><embed id="ZeroClipboardMovie_4" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="16" height="16" name="ZeroClipboardMovie_4" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=4&width=16&height=16" wmode="transparent"></div></div>
</div>
<ol class="dp-cpp" start="1" style="padding:0px; border:none; color:rgb(92,92,92); margin:0px 0px 1px 45px!important; background-color:rgb(255,255,255)">
<li class="alt" style="border-style:none none none solid; border-left-width:3px; border-left-color:rgb(108,226,108); list-style:decimal-leading-zero outside; color:inherit; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important">
<span style="margin:0px; padding:0px; border:none; color:black; background-color:inherit"><span style="margin:0px; padding:0px; border:none; background-color:inherit">ctx->tai = (TDI_ADDRESS_INFO *)malloc_np(TDI_ADDRESS_INFO_MAX);  </span></span></li><li style="border-style:none none none solid; border-left-width:3px; border-left-color:rgb(108,226,108); list-style:decimal-leading-zero outside; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important; background-color:rgb(248,248,248)">
<span style="margin:0px; padding:0px; border:none; color:black; background-color:inherit"> <span class="keyword" style="margin:0px; padding:0px; border:none; color:rgb(0,102,153); font-weight:bold; background-color:inherit">if</span><span style="margin:0px; padding:0px; border:none; background-color:inherit"> (ctx->tai == NULL) {  </span></span></li><li class="alt" style="border-style:none none none solid; border-left-width:3px; border-left-color:rgb(108,226,108); list-style:decimal-leading-zero outside; color:inherit; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important">
<span style="margin:0px; padding:0px; border:none; color:black; background-color:inherit">  KdPrint((<span class="string" style="margin:0px; padding:0px; border:none; color:blue; background-color:inherit">"[tdi_fw] tdi_create_addrobj_complete: malloc_np!\n"</span><span style="margin:0px; padding:0px; border:none; background-color:inherit">));  </span></span></li><li style="border-style:none none none solid; border-left-width:3px; border-left-color:rgb(108,226,108); list-style:decimal-leading-zero outside; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important; background-color:rgb(248,248,248)">
<span style="margin:0px; padding:0px; border:none; color:black; background-color:inherit">  </span></li><li class="alt" style="border-style:none none none solid; border-left-width:3px; border-left-color:rgb(108,226,108); list-style:decimal-leading-zero outside; color:inherit; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important">
<span style="margin:0px; padding:0px; border:none; color:black; background-color:inherit">  status = STATUS_INSUFFICIENT_RESOURCES;  </span></li><li style="border-style:none none none solid; border-left-width:3px; border-left-color:rgb(108,226,108); list-style:decimal-leading-zero outside; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important; background-color:rgb(248,248,248)">
<span style="margin:0px; padding:0px; border:none; color:black; background-color:inherit">  <span class="keyword" style="margin:0px; padding:0px; border:none; color:rgb(0,102,153); font-weight:bold; background-color:inherit">goto</span><span style="margin:0px; padding:0px; border:none; background-color:inherit"> done;  </span></span></li><li class="alt" style="border-style:none none none solid; border-left-width:3px; border-left-color:rgb(108,226,108); list-style:decimal-leading-zero outside; color:inherit; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important">
<span style="margin:0px; padding:0px; border:none; color:black; background-color:inherit"> }  </span></li></ol>
</div>
<p style="color:rgb(51,51,51); font-family:Arial; font-size:14px; line-height:26px">
<br>
<img alt="" src="http://img.my.csdn.net/uploads/201209/27/1348741219_3055.jpg" style="border:none; max-width:100%"></p>
<p style="color:rgb(51,51,51); font-family:Arial; font-size:14px; line-height:26px">
可以看到tai的首地址是0x82040928,這是一個非分頁內存中的虛擬地址,長度是0x55。</p>
<div class="dp-highlighter bg_cpp" style="font-family:Consolas,'Courier New',Courier,mono,serif; width:700.906px; overflow:auto; padding-top:1px; color:rgb(51,51,51); line-height:26px; margin:18px 0px!important; background-color:rgb(231,229,220)">
<div class="bar" style="padding-left:45px">
<div class="tools" style="padding:3px 8px 10px 10px; font-size:9px; line-height:normal; font-family:Verdana,Geneva,Arial,Helvetica,sans-serif; color:silver; border-left-width:3px; border-left-style:solid; border-left-color:rgb(108,226,108); background-color:rgb(248,248,248)">
<strong>[cpp]</strong> <a target="_blank" href="http://blog.csdn.net/chenyujing1234/article/details/8025968#" class="ViewSource" title="view plain" style="color:rgb(160,160,160); text-decoration:none; border:none; padding:1px; margin:0px 10px 0px 0px; font-size:9px; display:inline-block; width:16px; height:16px; text-indent:-2000px; background-color:inherit">view
 plain</a><a target="_blank" href="http://blog.csdn.net/chenyujing1234/article/details/8025968#" class="CopyToClipboard" title="copy" style="color:rgb(160,160,160); text-decoration:none; border:none; padding:1px; margin:0px 10px 0px 0px; font-size:9px; display:inline-block; width:16px; height:16px; text-indent:-2000px; background-color:inherit">copy</a>
<div style="position:absolute; left:510px; top:5528px; width:18px; height:18px; z-index:99">
</div>
<div style="position: absolute; left: 245px; top: 4972px; width: 16px; height: 16px; z-index: 99;"><embed id="ZeroClipboardMovie_5" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="16" height="16" name="ZeroClipboardMovie_5" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=5&width=16&height=16" wmode="transparent"></div></div>
</div>
<ol class="dp-cpp" start="1" style="padding:0px; border:none; color:rgb(92,92,92); margin:0px 0px 1px 45px!important; background-color:rgb(255,255,255)">
<li class="alt" style="border-style:none none none solid; border-left-width:3px; border-left-color:rgb(108,226,108); list-style:decimal-leading-zero outside; color:inherit; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important">
<span style="margin:0px; padding:0px; border:none; color:black; background-color:inherit"><span style="margin:0px; padding:0px; border:none; background-color:inherit">mdl = IoAllocateMdl(ctx->tai, TDI_ADDRESS_INFO_MAX, FALSE, FALSE, NULL);  </span></span></li><li style="border-style:none none none solid; border-left-width:3px; border-left-color:rgb(108,226,108); list-style:decimal-leading-zero outside; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important; background-color:rgb(248,248,248)">
<span style="margin:0px; padding:0px; border:none; color:black; background-color:inherit"> <span class="keyword" style="margin:0px; padding:0px; border:none; color:rgb(0,102,153); font-weight:bold; background-color:inherit">if</span><span style="margin:0px; padding:0px; border:none; background-color:inherit"> (mdl == NULL) {  </span></span></li><li class="alt" style="border-style:none none none solid; border-left-width:3px; border-left-color:rgb(108,226,108); list-style:decimal-leading-zero outside; color:inherit; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important">
<span style="margin:0px; padding:0px; border:none; color:black; background-color:inherit">  KdPrint((<span class="string" style="margin:0px; padding:0px; border:none; color:blue; background-color:inherit">"[tdi_fw] tdi_create_addrobj_complete: IoAllocateMdl!\n"</span><span style="margin:0px; padding:0px; border:none; background-color:inherit">));  </span></span></li><li style="border-style:none none none solid; border-left-width:3px; border-left-color:rgb(108,226,108); list-style:decimal-leading-zero outside; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important; background-color:rgb(248,248,248)">
<span style="margin:0px; padding:0px; border:none; color:black; background-color:inherit">    </span></li><li class="alt" style="border-style:none none none solid; border-left-width:3px; border-left-color:rgb(108,226,108); list-style:decimal-leading-zero outside; color:inherit; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important">
<span style="margin:0px; padding:0px; border:none; color:black; background-color:inherit">  status = STATUS_INSUFFICIENT_RESOURCES;  </span></li><li style="border-style:none none none solid; border-left-width:3px; border-left-color:rgb(108,226,108); list-style:decimal-leading-zero outside; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important; background-color:rgb(248,248,248)">
<span style="margin:0px; padding:0px; border:none; color:black; background-color:inherit">  <span class="keyword" style="margin:0px; padding:0px; border:none; color:rgb(0,102,153); font-weight:bold; background-color:inherit">goto</span><span style="margin:0px; padding:0px; border:none; background-color:inherit"> done;  </span></span></li><li class="alt" style="border-style:none none none solid; border-left-width:3px; border-left-color:rgb(108,226,108); list-style:decimal-leading-zero outside; color:inherit; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important">
<span style="margin:0px; padding:0px; border:none; color:black; background-color:inherit"> }   </span></li></ol>
</div>
<p style="color:rgb(51,51,51); font-family:Arial; font-size:14px; line-height:26px">
分配MDL之後的內存:</p>
<p style="color:rgb(51,51,51); font-family:Arial; font-size:14px; line-height:26px">
<img alt="" src="http://img.my.csdn.net/uploads/201209/27/1348741270_8539.jpg" style="border:none; max-width:100%"></p>
<p style="color:rgb(51,51,51); font-family:Arial; font-size:14px; line-height:26px">
其中MDL的首地址是0x82010210,size是32,這是MDL結構本身的大小,mdlflags是8,mappedsystemva的值是0xf8c9oa9c</p>
<p style="color:rgb(51,51,51); font-family:Arial; font-size:14px; line-height:26px">
startva是0x82040000,這說明startva目前表示的是tai所指向的虛擬地址的頁起始地址,bytecount是55,這代表了虛擬地址的大小,byteoffset是0x929,因此這個字節表示的是虛擬地址相對於頁的偏移地址。<br>
 MmBuildMdlForNonPagedPool(mdl);</p>
<p style="color:rgb(51,51,51); font-family:Arial; font-size:14px; line-height:26px">
調用此函數之後:</p>
<p style="color:rgb(51,51,51); font-family:Arial; font-size:14px; line-height:26px">
<img alt="" src="http://img.my.csdn.net/uploads/201209/27/1348741312_5913.jpg" style="border:none; max-width:100%"></p>
<p style="color:rgb(51,51,51); font-family:Arial; font-size:14px; line-height:26px">
 </p>
<p style="color:rgb(51,51,51); font-family:Arial; font-size:14px; line-height:26px">
僅有3個字段發生了變化</p>
<p style="color:rgb(51,51,51); font-family:Arial; font-size:14px; line-height:26px">
mdlflags變成了12,mappedsystemva真正指向了虛擬地址,process被置0,說明這是一個非分頁地址,它不屬於任何一個進程的地址空間。</p>
<p style="color:rgb(51,51,51); font-family:Arial; font-size:14px; line-height:26px">
實際上size的大小並不等於MDL結構的大小,因爲在MDL後面緊跟着一個表示物理頁面的數組,只是沒有在結構體中表現出來,這應該是爲了避免一般的驅動程序直接修改這些物理數組,因爲虛擬地址和物理頁面的映射只應該由內存管理器來維護。在剛纔的調試中觀察內存發現,在MDL後面只有一個物理頁面編號。此編號在調用IoAllocateMdl的時候並未初始化,而是在 MmBuildMdlForNonPagedPool(mdl)中被賦的值。有些人認爲 MmBuildMdlForNonPagedPool是把物理頁面映射到系統地址空間中,這種說法應該是錯誤的,因爲對於非分頁內存,在調用ExAllocatePool系列函數的時候,內存管理器就建立了映射關係,否則這些內存根本無法使用,實際上, MmBuildMdlForNonPagedPool的作用是把這種映射保存到MDL中,使其變得不透明,以滿足某些驅動的需求。</p>
<p style="color:rgb(51,51,51); font-family:Arial; font-size:14px; line-height:26px">
三,MDL的使用</p>
<p style="color:rgb(51,51,51); font-family:Arial; font-size:14px; line-height:26px">
 典型的,當運行在內核中的一個驅動向另一個驅動發送請求的時候,其中一種數據傳輸方式將運用到MDL。</p>
<p style="color:rgb(51,51,51); font-family:Arial; font-size:14px; line-height:26px">
首先調用IoAllocateMdl對你需要傳遞的數據生成一個MDL,它會返回一個MDL結構的指針,然後調用MmBuildMdlForNonPagedPool來更新MDL的內容,最後把這個MDL指針傳遞給IRP中的MdlAddress成員。</p>
<p style="color:rgb(51,51,51); font-family:Arial; font-size:14px; line-height:26px">
 </p>
<p style="color:rgb(51,51,51); font-family:Arial; font-size:14px; line-height:26px; text-indent:2em">
順便說一下,我們不可以直接訪問MDL的任何成員。應該使用宏或訪問函數,</p>
<p style="color:rgb(51,51,51); font-family:Arial; font-size:14px; line-height:26px">
<img alt="" src="http://img.my.csdn.net/uploads/201209/27/1348741356_2713.jpg" style="border:none; max-width:100%"></p>
<p style="color:rgb(51,51,51); font-family:Arial; font-size:14px; line-height:26px; text-indent:2em">
對於I/O管理器執行的Direct方式的讀寫操作,其過程可以想象爲下面代碼:</p>
<div class="dp-highlighter bg_cpp" style="font-family:Consolas,'Courier New',Courier,mono,serif; width:700.906px; overflow:auto; padding-top:1px; color:rgb(51,51,51); line-height:26px; margin:18px 0px!important; background-color:rgb(231,229,220)">
<div class="bar" style="padding-left:45px">
<div class="tools" style="padding:3px 8px 10px 10px; font-size:9px; line-height:normal; font-family:Verdana,Geneva,Arial,Helvetica,sans-serif; color:silver; border-left-width:3px; border-left-style:solid; border-left-color:rgb(108,226,108); background-color:rgb(248,248,248)">
<strong>[cpp]</strong> <a target="_blank" href="http://blog.csdn.net/chenyujing1234/article/details/8025968#" class="ViewSource" title="view plain" style="color:rgb(160,160,160); text-decoration:none; border:none; padding:1px; margin:0px 10px 0px 0px; font-size:9px; display:inline-block; width:16px; height:16px; text-indent:-2000px; background-color:inherit">view
 plain</a><a target="_blank" href="http://blog.csdn.net/chenyujing1234/article/details/8025968#" class="CopyToClipboard" title="copy" style="color:rgb(160,160,160); text-decoration:none; border:none; padding:1px; margin:0px 10px 0px 0px; font-size:9px; display:inline-block; width:16px; height:16px; text-indent:-2000px; background-color:inherit">copy</a>
<div style="position:absolute; left:510px; top:7289px; width:18px; height:18px; z-index:99">
</div>
<div style="position: absolute; left: 245px; top: 6707px; width: 16px; height: 16px; z-index: 99;"><embed id="ZeroClipboardMovie_6" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="16" height="16" name="ZeroClipboardMovie_6" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=6&width=16&height=16" wmode="transparent"></div></div>
</div>
<ol class="dp-cpp" start="1" style="padding:0px; border:none; color:rgb(92,92,92); margin:0px 0px 1px 45px!important; background-color:rgb(255,255,255)">
<li class="alt" style="border-style:none none none solid; border-left-width:3px; border-left-color:rgb(108,226,108); list-style:decimal-leading-zero outside; color:inherit; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important">
<span style="margin:0px; padding:0px; border:none; color:black; background-color:inherit"><span style="margin:0px; padding:0px; border:none; background-color:inherit">KPROCESSOR_MODE mode; </span><span class="comment" style="margin:0px; padding:0px; border:none; color:rgb(0,130,0); background-color:inherit">// either KernelMode or UserMode PMDL mdl = IoAllocateMdl(uva, length, FALSE, TRUE, Irp);</span><span style="margin:0px; padding:0px; border:none; background-color:inherit">  </span></span></li><li style="border-style:none none none solid; border-left-width:3px; border-left-color:rgb(108,226,108); list-style:decimal-leading-zero outside; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important; background-color:rgb(248,248,248)">
<span style="margin:0px; padding:0px; border:none; color:black; background-color:inherit"> MmProbeAndLockPages(mdl, mode, reading ? IoWriteAccess : IoReadAccess);   </span></li><li class="alt" style="border-style:none none none solid; border-left-width:3px; border-left-color:rgb(108,226,108); list-style:decimal-leading-zero outside; color:inherit; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important">
<span style="margin:0px; padding:0px; border:none; color:black; background-color:inherit"><code to send and await IRP> MmUnlockPages(mdl); ExFreePool(mdl);  </span></li></ol>
</div>
<p style="color:rgb(51,51,51); font-family:Arial; font-size:14px; line-height:26px; text-indent:2em">
I/O管理器首先創建一個描述用戶緩衝區的MDL。IoAllocateMdl的第三個參數(FALSE)指出這是一個主數據緩衝區。第四個參數(TRUE)指出內存管理器應把該內存充入進程配額。最後一個參數(Irp)指定該MDL應附着的IRP。在內部,IoAllocateMdl把Irp->MdlAddress設置爲新創建MDL的地址,以後你將用到這個成員,並且I/O管理器最後也使用該成員來清除MDL。</p>
<p style="color:rgb(51,51,51); font-family:Arial; font-size:14px; line-height:26px; text-indent:2em">
這段代碼的關鍵地方是調用MmProbeAndLockPages(以粗體字顯示)。該函數校驗那個數據緩衝區是否有效,是否可以按適當模式訪問。如果我們向設備寫數據,我們必須能讀緩衝區。如果我們從設備讀數據,我們必須能寫緩衝區。另外,該函數鎖定了包含數據緩衝區的物理內存頁,並在MDL的後面填寫了頁號數組。在效果上,一個鎖定的內存頁將成爲非分頁內存池的一部分,直到所有對該頁內存加鎖的調用者都對其解了鎖。</p>
<p style="color:rgb(51,51,51); font-family:Arial; font-size:14px; line-height:26px; text-indent:2em">
在Direct方式的讀寫操作中,對MDL你最可能做的事是把它作爲參數傳遞給其它函數。例如,DMA傳輸的MapTransfer步驟需要一個MDL。另外,在內部,USB讀寫操作總使用MDL。所以你應該把讀寫操作設置爲DO_DIRECT_IO方式,並把結果MDL傳遞給USB總線驅動程序。</p>
<p style="color:rgb(51,51,51); font-family:Arial; font-size:14px; line-height:26px; text-indent:2em">
順便提一下,I/O管理器確實在stack->Parameters聯合中保存了讀寫請求的長度,但驅動程序應該直接從MDL中獲得請求數據的長度。</p>
<div class="dp-highlighter bg_cpp" style="font-family:Consolas,'Courier New',Courier,mono,serif; width:700.906px; overflow:auto; padding-top:1px; color:rgb(51,51,51); line-height:26px; margin:18px 0px!important; background-color:rgb(231,229,220)">
<div class="bar" style="padding-left:45px">
<div class="tools" style="padding:3px 8px 10px 10px; font-size:9px; line-height:normal; font-family:Verdana,Geneva,Arial,Helvetica,sans-serif; color:silver; border-left-width:3px; border-left-style:solid; border-left-color:rgb(108,226,108); background-color:rgb(248,248,248)">
<strong>[cpp]</strong> <a target="_blank" href="http://blog.csdn.net/chenyujing1234/article/details/8025968#" class="ViewSource" title="view plain" style="color:rgb(160,160,160); text-decoration:none; border:none; padding:1px; margin:0px 10px 0px 0px; font-size:9px; display:inline-block; width:16px; height:16px; text-indent:-2000px; background-color:inherit">view
 plain</a><a target="_blank" href="http://blog.csdn.net/chenyujing1234/article/details/8025968#" class="CopyToClipboard" title="copy" style="color:rgb(160,160,160); text-decoration:none; border:none; padding:1px; margin:0px 10px 0px 0px; font-size:9px; display:inline-block; width:16px; height:16px; text-indent:-2000px; background-color:inherit">copy</a>
<div style="position:absolute; left:510px; top:7809px; width:18px; height:18px; z-index:99">
</div>
<div style="position: absolute; left: 245px; top: 7179px; width: 16px; height: 16px; z-index: 99;"><embed id="ZeroClipboardMovie_7" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="16" height="16" name="ZeroClipboardMovie_7" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=7&width=16&height=16" wmode="transparent"></div></div>
</div>
<ol class="dp-cpp" start="1" style="padding:0px; border:none; color:rgb(92,92,92); margin:0px 0px 1px 45px!important; background-color:rgb(255,255,255)">
<li class="alt" style="border-style:none none none solid; border-left-width:3px; border-left-color:rgb(108,226,108); list-style:decimal-leading-zero outside; color:inherit; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important">
<span style="margin:0px; padding:0px; border:none; color:black; background-color:inherit"><span class="datatypes" style="margin:0px; padding:0px; border:none; color:rgb(46,139,87); font-weight:bold; background-color:inherit">ULONG</span><span style="margin:0px; padding:0px; border:none; background-color:inherit"> length = MmGetMdlByteCount(mdl);
  </span></span></li></ol>
</div>
                    

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章