使用靜態驅動程式驗證器尋找 Windows 驅動程式中的瑕疵

靜態驅動程式驗證程式 (SDV) 會使用一組介面規則和作業系統的模型來判斷驅動程式是否與 Windows 作業系統正確互動。 SDV 在驅動程式程式碼中發現可能指向驅動程式中潛在 Bug 的瑕疵。

SDV 可以分析符合下列其中一個驅動程式模型的核心模式驅動程式:WDM、KMDF、NDIS 或 Storport。 如需詳細資訊,請參閱 支援的驅動程式判斷靜態驅動程式驗證器是否支援驅動程式或程式庫。 此外,SDV 為未遵循上述驅動程式模型的驅動程式提供有限的支援 (著重于一般錯誤的嚴重限制規則集,例如 null 取值) 。

準備原始程式碼

使用下列步驟來準備程式碼以供分析。

  1. 使用函式角色類型宣告驅動程式提供的函式

    SDV 需要使用函式角色類型宣告來宣告函式。 例如, DriverEntry 常式必須使用DRIVER_INITIALIZE函式角色類型來宣告:

    DRIVER_INITIALIZE DriverEntry;
    

    宣告之後,您可以實作 (或定義) 回呼常式,如下所示:

    /
    // Driver initialization routine
    //
    NTSTATUS
      DriverEntry(
        _In_ struct _DRIVER_OBJECT  *DriverObject,
        _In_ PUNICODE_STRING  RegistryPath
        )
      {
          // Function body
      }
    

    每個支援的驅動程式模型都有一組函式角色類型,適用于驅動程式回呼函式和分派常式。 這些函式角色類型會在 WDK 標頭檔中宣告。 例如,以下是DRIVER_INITIALIZE角色類型的函式原型,如 Wdm.h 所示。

    /
    // Define driver initialization routine type.
    //
    _Function_class_(DRIVER_INITIALIZE)
    _IRQL_requires_same_
    typedef
    NTSTATUS
    DRIVER_INITIALIZE (
        _In_ struct _DRIVER_OBJECT *DriverObject,
        _In_ PUNICODE_STRING RegistryPath
        );
    
    typedef DRIVER_INITIALIZE *PDRIVER_INITIALIZE;
    

    由於函式角色類型已在 WDK 標頭檔中定義,因此您只需要將回呼函式宣告為該類型。 在此情況下,您會宣告 DriverEntry 的類型為 DRIVER_INITIALIZE。 如需驅動程式模型函式角色類型的完整清單,請參閱 使用函式角色類型宣告

  2. 執行 C/C++ 的程式碼分析

    若要協助您判斷原始程式碼是否已備妥,請在 Visual Studio 中執行程式 代碼分析工具 。 程式碼分析工具會檢查 SDV 所需的函式角色類型宣告。 程式碼分析工具可協助識別任何可能遺漏的函式宣告,或當函式定義的參數不符合函式角色類型的參數時,警告您。

    • 在 Visual Studio 中開啟您的驅動程式專案。
    • 從 [ 建置] 功能表中,按一下 [ 在方案上執行程式碼分析]。

    結果會顯示在 [ 程式碼分析 ] 視窗中。 修正您可能遺漏的任何函式宣告。 您也可以設定程式碼分析工具,以便在您建置解決方案時執行。

    下表顯示程式碼分析工具可能會在驅動程式程式碼中找到的一些警告。 若要執行靜態驅動程式驗證器,您的驅動程式必須沒有這些瑕疵。

    C/C++ 警告的程式碼分析 描述
    C28101 Drivers 模組已推斷目前的函式是函 < 式類型 > 函式
    C28022 此函式上的函式類別 (es) 不符合用來定義函式的 typedef (es) 。
    C28023 指派或傳遞的函式應該至少有一個類別的_Function_class_注釋, (es)
    C28024 指派給 的函式指標會以函式類別標注,此類別不包含在函式類別中, (es) 清單。
    C28169 分派函式 <> 函式沒有任何_Dispatch_type_批註
    C28208 函式簽章與函式宣告不符

執行靜態驅動程式驗證器

  1. 在 Visual Studio 中開啟驅動程式專案 (.vcxProj) 檔案。 從 [ 驅動程式 ] 功能表中,按一下 [ 啟動靜態驅動程式驗證程式...]。

    這會開啟靜態驅動程式驗證器應用程式,您可以在其中控制、設定及排程靜態驅動程式驗證器執行分析。

  2. 如果您的驅動程式包含程式庫,請按一下 [連結 ] 索引標籤,然後按一下 [ 新增程式庫 ] 以新增程式庫。

    流覽至程式庫原始程式碼的目錄,然後選取專案檔 (.vcxProj) 。 新增驅動程式包含的所有程式庫。 在 SDV 分析驅動程式之前,必須先新增程式庫。 當您開始分析驅動程式時,SDV 也會分析尚未處理的程式庫。 處理程式庫之後,它會儲存在全域 SDV 快取中。 如需詳細資訊,請參閱 靜態驅動程式驗證器中的程式庫處理

  3. 檢查靜態驅動程式驗證器的組態設定。 按一下 [設定] 索引標籤。

    專案組態 [專案組態] 會顯示您在 Visual Studio 中選取的組態和平臺設定。

    資源 在大部分情況下,您可以使用預設設定。 如果 SDV 報告 Timeout、GiveUp 或 Spaceout,您可以嘗試調整這些設定。 如需詳細資訊,請參閱 針對靜態驅動程式驗證程式進行疑難排解的建議

    附表 選取開始驗證的開始時間。 預設設定是在按一下 [主要] 索引標籤上的 [開始] 之後立即開始分析。根據驅動程式的大小及其複雜性,靜態分析可能需要很長的時間才能執行。 您可能會想要排程分析,以在最方便時開始;例如,在一天結束時。

    注意

    ]請務必檢查電腦的電源管理計畫,以確保電腦在分析期間不會進入睡眠狀態。

  4. 按一下 [ 規則] 索引 標籤,以選取哪些驅動程式 API 使用規則,以在開始分析時進行驗證。

    靜態驅動程式驗證器會偵測您要分析的驅動程式類型, (WDF、WDM、NDIS 或 Storport) ,並選取驅動程式類型的預設規則集。 如果這是您第一次在驅動程式上執行 SDV,您應該執行預設規則集。

    如需規則的相關資訊,請參閱 DDI 合規性規則

  5. 啟動靜態分析。 按一下 [主要] 索引卷 標,然後按一下 [ 開始]。 當您按一下 [ 開始] 時,會顯示一則訊息,讓您知道已排程靜態分析,而且分析可能需要很長的時間才能執行。 按一下 [確定] 繼續進行。 分析會從您排程的時間開始。

檢視和分析結果

當靜態分析繼續進行時,SDV 會報告分析的狀態。 當分析完成時,SDV 會報告結果和統計資料。 如果驅動程式無法滿足 API 使用規則,結果會回報為瑕疵。

如果遇到任何問題,SDV 會在 [ 警告 ] 和 [ 錯誤 ] 頁面上顯示這些問題。 [ 驅動程式屬性] 頁面會顯示特定驅動程式屬性的測試結果。 驅動程式屬性測試可用來識別驅動程式功能,以進一步限定分析。 您可以使用 驅動程式屬性 結果來確認驅動程式的預期屬性和支援的功能。

若要在 靜態驅動程式驗證器報告中檢視特定瑕疵,請按一下 [ 結果 ] 窗格中的 [瑕疵]。 這會開啟 追蹤檢視器,以顯示規則違規程序代碼路徑的追蹤。 如需詳細資訊,請參閱 解譯靜態驅動程式驗證器結果

注意

靜態驅動程式驗證器會保留分析的結果和設定。 若要清除結果,請按一下 [ 清除]。

針對靜態驅動程式驗證器結果進行疑難排解

如果 SDV 回報找不到瑕疵,請檢查 [主要 ] 索引標籤,以確保偵測到進入點。 如果驅動程式未使用函式角色類型來宣告函式,SDV 將無法分析並找出驅動程式程式碼中的瑕疵。 如需詳細資訊,請參閱 使用函式角色類型宣告

如果 SDV 回報逾時或無法傳回有用的結果,您可能需要變更幾個 SDV 組態選項。 如需如何針對 SDV 進行疑難排解的詳細資訊,請參閱 針對靜態驅動程式驗證程式進行疑難排解的建議

判斷靜態驅動程式驗證器是否支援您的驅動程式或程式庫

使用函式角色類型宣告

靜態驅動程式驗證器規則

程式碼分析工具