靜態和動態驗證工具
驗證工具有兩種基本類型:
靜態驗證工具 會檢查驅動程式程式代碼,而不執行驅動程式。 由於這些工具不依賴執行程式碼的測試,因此可能非常徹底。 理論上,靜態驗證工具可以檢查所有驅動程式程式代碼,包括實務上很少執行的程式代碼路徑。 不過,由於驅動程式並未實際執行,因此可能會產生誤判結果。 也就是說,它們可能會回報程式代碼路徑中可能未實際發生的錯誤。
動態驗證工具 會在驅動程式執行時檢查驅動程式程式代碼,通常是攔截常用驅動程序支援例程的呼叫,並取代對相同例程本身錯誤檢查版本的呼叫。 因為驅動程序實際上是在動態工具執行驗證時執行,因此誤判結果很少見。 不過,由於動態工具只會偵測在監視驅動程式時發生的動作,因此如果驅動程式測試涵蓋範圍不足,工具可能會遺漏某些驅動程式缺陷。 同時,藉由使用運行時間可用的資訊,例如,從原始程式碼靜態擷取更難的資訊,動態驗證工具可以偵測某些類別的驅動程序錯誤,而使用靜態分析工具更難偵測。
最佳做法是使用靜態和動態驗證工具的組合。 靜態工具可讓您檢查在實務上難以練習的程式代碼路徑,而動態工具則發現驅動程式中發生的嚴重錯誤。
重要
Windows 硬體相容性計劃需要 CodeQL,在我們的用戶端和伺服器作業系統上進行靜態工具標誌 (STL) 測試。 我們將繼續在舊版產品上維護 SDV 和 CA 的支援。 強烈建議合作夥伴檢閱靜態工具標誌測試的程式代碼QL需求。 如需使用 CodeQL 的詳細資訊,請參閱 CodeQL 和靜態工具標誌測試。
驗證工具調查
WDK 說明下列驗證工具,並建議驅動程式開發人員和測試人員使用。 它們會依通常使用的順序列出。
一旦程式代碼編譯
- 由 GitHub 撰寫的 CodeQL 是功能強大的語意程式代碼分析引擎,以及廣泛的高價值安全性查詢套件組合,以及強固的平臺,使其成為保護驅動程式程式代碼的寶貴工具。 如需詳細資訊,請參閱 CodeQL 和靜態工具標誌測試。
其他靜態工具
視您建置驅動程式的 Windows 版本而定,可能需要其他靜態工具。
驅動程式 的程式代碼分析是在編譯時期執行的靜態驗證工具。 驅動程式的程式代碼分析可以驗證以 C/C++ 和 Managed 程式代碼撰寫的驅動程式。 它會獨立檢查驅動程式每個函式中的程式碼,因此您可以一旦建置驅動程式即可立即執行。 其執行速度相對較快,且使用少數資源。
Visual Studio 中程式代碼分析工具的基本功能會偵測一般編碼錯誤,例如不檢查傳回值。 驅動程式特定功能會偵測更細微的驅動程式編碼錯誤,例如將未初始化的欄位留在複製的 IRP 中,並在例程結束時無法還原變更的 IRQL。
靜態驅動程式驗證器 (SDV) 是靜態驗證工具,可在編譯階段執行,並驗證以 C/C++ 撰寫的核心模式驅動程式程式代碼。 它包含在 WDK 中,而且可以使用 MSBuild 從 Visual Studio Ultimate 2012 或 Visual Studio 命令提示字元窗口啟動。
根據一組介面規則和操作系統的模型,靜態驅動程序驗證器會判斷驅動程式是否與 Windows 操作系統核心正確互動。 靜態驅動程式驗證器非常徹底 -- 它會探索驅動程式原始程式碼中的所有可連線路徑,並以符號方式執行它們。 因此,它會尋找使用任何其他傳統驅動程序測試方法未偵測到的 Bug。
重要
不再支援 SDV,且 Windows 24H2 WDK 或 EWDK 版本無法使用 SDV。 它不適用於比組建 26017 還新的 WDK,而且不包含在 Windows 24H2 RTM WDK 中。
從下載 Windows 驅動程式套件 (WDK) 下載 Windows 11 版本 22H2 EWDK(2023 年 10 月 24 日發行)與 Visual Studio 組建工具 17.1.5,仍然可以使用 SDV。 建議只使用企業 WDK 來執行 SDV。 不建議使用舊版的標準 WDK 搭配最新版的 Visual Studio,因為這可能會導致分析失敗。
接下來,CodeQL 將是驅動程式的主要靜態分析工具。 CodeQL 提供功能強大的查詢語言,會將程式代碼視為要查詢的資料庫,讓您輕鬆地撰寫查詢特定行為、模式等等。
如需使用 CodeQL 的詳細資訊,請參閱 CodeQL 和靜態工具標誌測試。
驅動程式執行時
一旦建置驅動程式且正在執行且沒有明顯錯誤,請使用下列動態驗證工具。
驅動程式驗證器 是專為 Windows 驅動程式撰寫的動態驗證工具。 它包含多個可以同時在數個驅動程式上執行的測試。 驅動程式驗證器對於在驅動程式中尋找嚴重 Bug 非常有效,而有經驗的驅動程式開發人員和測試人員會設定驅動程式驗證器,以便在其驅動程式在開發或測試環境中執行時執行。 驅動程式驗證器包含在 Windows 中。 當您為驅動程式啟用驅動程式驗證器時,您也必須在驅動程式上執行多個測試。 驅動程式驗證器可以單獨使用靜態驗證工具來偵測難以偵測的特定驅動程序錯誤。 這些 Bug 類型的範例包括下列各項:
核心集區緩衝區滿溢。 當已驗證的驅動程式配置集區內存緩衝區時,驅動程式驗證器會使用無法存取的記憶體頁面來保護它們。 如果驅動程式嘗試使用超過緩衝區結尾的記憶體,驅動程式驗證程式將會發出錯誤檢查。
釋放記憶體之後使用記憶體。 特殊集區內存區塊會使用自己的記憶體頁面,而且不會與其他配置共用記憶體頁面。 當驅動程式釋放集區內存區塊時,對應的記憶體頁面會變成無法存取。 如果驅動程式在釋放記憶體之後嘗試使用該記憶體,驅動程式會立即當機。
在提升許可權的 IRQL 執行時,使用可分頁記憶體。 當已驗證的驅動程式在 DISPATCH_LEVEL 或更高版本引發 IRQL 時,驅動程式驗證器會從系統工作集修剪所有可分頁記憶體,並在記憶體壓力下模擬系統。 如果驅動程式嘗試使用其中一個可分頁的虛擬位址,驅動程式就會當機。
低資源模擬。 若要在低資源條件下模擬系統,驅動程式驗證器可能會讓驅動程式呼叫的各種操作系統核心 API 失敗。
記憶體流失。 驅動程式驗證器會追蹤驅動程式所進行的記憶體配置,並確定驅動程式卸除之前會釋放記憶體。
需要太多時間才能完成或取消的 I/O 作業。 驅動程式驗證器可以測試驅動程序的邏輯,以回應來自IoCallDriver的STATUS_PENDING傳回值。
DDI 合規性檢查。 (從 Windows 8 開始提供)驅動程式驗證器會套用一組設備驅動器介面 (DDI) 規則,以檢查驅動程式與作業系統核心介面之間的適當互動。 這些規則會對應至靜態驅動程式驗證器在分析驅動程式原始程式碼時所使用的規則。 如果驅動程式驗證器在啟用 DDI 合規性檢查時發現錯誤,請執行 靜態驅動程式驗證器 ,然後選取導致錯誤的相同規則。 靜態驅動程式驗證器可協助您找出驅動程式原始程式碼中瑕疵的原因。
核心 位址清理程式 (KASAN) 是 Windows 驅動程式上支援的 Bug 偵測技術,可讓您偵測數種不合法的記憶體存取類別,例如緩衝區溢位和使用後無事件。
應用程式驗證器 是一種動態驗證工具,適用於以 C/C++撰寫的使用者模式應用程式和驅動程式。 它不會驗證Managed程式碼。