驅動程式驗證器中的特殊集區內存損毀偵測
記憶體損毀是常見的驅動程序問題。 驅動程式錯誤可能會導致錯誤在發生錯誤之後長時間損毀。 最常見的錯誤是存取已釋放的記憶體,並配置 n 個字節,然後存取 n+1 個字節。
若要偵測記憶體損毀,驅動程式驗證器可以從特殊集區配置驅動程式記憶體,並監視該集區是否有不正確的存取。 系統會針對核心模式系統提供的例程提供特殊集區支援,例如 ExAllocatePoolWithTag ,以及 GDI 系統提供的例程,例如 EngAllocMem。
依對齊方式的特殊集區
有兩個特殊集區的對齊方式可供使用:
- [驗證開始] 對齊方式更適合用來偵測存取不足。
- 驗證結束對齊方式更適合偵測存取溢出。
如需如何使用 [驗證開始 ] 和 [ 驗證結束 ] 選項的詳細資訊,請參閱 偵測溢出和不足。 請注意,大部分的記憶體損毀是因為 過度執行,而不是不足。
當特殊集區功能處於作用中狀態且已選取 [驗證結束 ] 時,驅動程式所要求的每個記憶體配置都會放在不同的頁面上。 傳回允許配置容納在頁面上的最高可能位址,讓記憶體與頁面結尾對齊。 頁面的上一個部分會以特殊模式撰寫。 上一頁和下一頁標示為無法存取。
如果驅動程式嘗試在配置結束時存取記憶體,驅動程式驗證程式將會立即偵測到此情況,併發出 錯誤檢查0xCD。 如果驅動程式在緩衝區開頭之前的記憶體中寫入,這 (可能會) 改變模式。 釋放緩衝區時,驅動程式驗證器會偵測變更併發出 錯誤檢查0xC1。
如果驅動程式在釋放緩衝區之後讀取或寫入緩衝區,驅動程式驗證程式會發出 錯誤檢查0xCC。
選取 [確認開始] 時,記憶體緩衝區會與頁面的開頭對齊。 使用此設定時,下溢會導致立即錯誤檢查,而溢出會在釋放記憶體時造成錯誤檢查。 此選項與其他 [驗證結束] 選項相同。
確認 End 是預設對齊方式,因為過度執行錯誤在驅動程式中比不足的錯誤更常見。
個別記憶體配置可以覆寫這些設定,並藉由呼叫 ExAllocatePoolWithTagPriority ,並將 Priority 參數設定為 XxxSpecialPoolOverrun 或 XxxSpecialPoolUnderrun 來選擇其對齊方式。 (此例程無法啟用或停用特殊集區功能,或要求特殊集區進行記憶體配置,否則會從一般集區配置。只有對齊方式可以從這個例程控制。)
在 Windows 7 和更新版本的 Windows 作業系統中,[特殊集區] 選項支援使用下列核心 API 配置的記憶體:
IoAllocateIrp 和其他可配置 I/O 要求封包的例程, (IRP) 數據結構
RtlAnsiStringToUnicodeString 和其他運行時間連結庫 (RTL) 字串例程
依集區標籤或配置大小的特殊集區
除了驅動程序驗證器的特殊集區功能之外,還會要求特殊集區供指定的 驅動程式配置,還有兩種方式可以使用特殊集區:
集區標籤。 針對具有指定集區標籤的所有配置要求特殊集區。
大小。 針對指定大小範圍內的所有配置要求特殊集區。
若要要求集區標籤或大小範圍的特殊集區,請使用 Gflags,這是 Windows 偵錯工具中包含的工具。 如需詳細資訊,請參閱 使用全域旗標公用程式。
您可以使用驅動程式驗證器的特殊集區功能,以及 Gflags 的特殊集區功能。 如果您這麼做,請記住特殊集區有限,並非所有嘗試從特殊集區配置都成功,而且 Windows 會針對失敗嘗試從一般記憶體集區配置滿足的特殊集區傳回成功狀態。
特殊集區效率
並非所有特殊集區要求都已完成。 特殊集區中的每個配置都會使用一頁不可分頁的實體記憶體和兩個虛擬位址空間頁面。 如果集區耗盡,記憶體會以標準方式配置,直到特殊集區再次可用為止。 從標準集區填入特殊集區要求時,要求函式不會傳回錯誤,因為集區要求已成功。 因此,如果特殊集區功能已啟用,則不建議同時驗證多個驅動程式。
讓許多小型記憶體要求的單一驅動程式也可以耗用此集區。 如果發生這種情況,最好是將集區卷標指派給驅動程式的記憶體配置,並一次將特殊集區專用至一個集區標籤。
特殊集區的大小隨著系統上的實體記憶體數量而增加;在理想情況下,這至少應該是 1 GB (GB) 。 在 x86 計算機上,因為除了耗用實體) 空間之外,虛擬 (,請勿使用 /3GB 開機選項。 此外,最好將頁面檔最小/最大數量增加為 2 或 3 的因數。
為了確保所有驅動程式的配置都經過測試,建議在很長一段時間內強調驅動程式。
監視特殊集區
您可以監視與集區配置相關的統計數據。 這些可由驅動程式驗證器管理員、Verifier.exe 命令行或記錄檔顯示。 如需詳細資訊 ,請參閱監視全域計數器 。
如果 特殊集區計數器中的集區配置成功 等於集區 配置成功 計數器,則特殊集區已足以涵蓋所有記憶體配置。 如果前一個計數器低於後者,則特殊集區至少已耗盡一次。
這些計數器不會追蹤其大小為一頁或更大的配置,因為特殊集區不適用於它們。
如果啟用特殊集區功能,但已從特殊集區指派少於 95% 的集區配置,驅動程式驗證器管理員中會出現警告。 在 Windows 2000 中,此警告會出現在 [驅動程序狀態 ] 畫面上。 在 Windows XP 和更新版本中,此警告會出現在 [全域計數器 ] 畫面上。 如果發生這種情況,您應該驗證較短的驅動程式清單、依集區卷標驗證個別集區,或將更多實體記憶體新增至您的系統。
核心調試程式擴充 功能 !verifier 也可以用來監視特殊集區使用。 它會顯示與驅動程式驗證器管理員類似的資訊。 如需調試程式延伸模組的詳細資訊,請參閱 Windows 偵錯。
啟用特殊集區選項
您可以使用驅動程式驗證器管理員或 Verifier.exe 命令行,為一或多個驅動程式啟用特殊集區功能。 如需詳細資訊,請參閱 選取驅動程式驗證器選項。
注意
若要依集區標籤或配置大小啟動特殊集區功能,或設定 [驗證開始 ] (偵測下溢) 和 [驗證結束 (偵測溢出) 對齊方式,請使用 全域旗標公用程式;這些對齊設定適用於所有特殊集區配置。
在命令行
在命令行中,[特殊集區] 選項是由 位 0 (0x1) 表示。 若要啟用特殊集區,請使用旗標值0x1,或將0x1新增至旗標值。 例如:
verifier /flags 0x1 /driver MyDriver.sys
下一次開機之後,此功能將會處於作用中狀態。
Y 您也可以將 /volatile 參數新增至 命令,以啟動和停用特殊集區,而不重新啟動計算機。 例如:
verifier /volatile /flags 0x1 /adddriver MyDriver.sys
此設定會立即生效,但當您關閉或重新啟動電腦時遺失。 如需詳細資訊,請參閱 使用變動性設定。
特殊集區功能也會包含在標準設定中。 例如:
verifier /standard /driver MyDriver.sys
使用驅動程式驗證器管理員
- 選取 [為程式代碼開發人員建立自定義設定] () ,然後按 [ 下一步]。
- 從完整清單中選取 [選取個別設定]。
- 選取 [ (檢查 [ 特殊集區]) 。
特殊集區功能也會包含在標準設定中。 若要使用此功能,請在 [驅動程序驗證器管理員] 中,按兩下 [ 建立標準設定]。