共用方式為


句柄管理

驅動程式內安全性問題的一個重大來源是使用在使用者模式與核心模式元件之間傳遞的控制代碼。 核心環境中的句柄使用有許多已知問題,包括下列內容:

  • 將錯誤類型控制碼傳遞至核心驅動程式的應用程式。 核心驅動程式可能會在嘗試使用需要檔案物件的事件物件時當機。

  • 將控制碼傳遞至其沒有必要存取權的物件的應用程式。 核心驅動程式可能會執行一個能成功的操作,因為該呼叫來自核心模式,即便使用者沒有足夠的權限。

  • 傳遞值的應用程式,其值在其位址空間中不是有效的控制碼,但會標示為系統控制碼,以對系統執行惡意作業。

  • 某應用程式傳遞的值不是裝置物件的適當控制碼(即此驅動程式未建立的控制碼)。

為了防止這些問題,核心驅動程式必須特別小心,以確保傳遞給它的控制碼有效。 最安全的原則是在驅動程式的內容中建立任何必要的控制碼。 這些由核心驅動程式建立的控制碼應該指定 OBJ_KERNEL_HANDLE 選項,這會建立在任意進程內容中有效的控制碼,以及只能從核心模式呼叫端存取的控制碼。

對於使用應用程式所建立控制碼的驅動程式,必須非常小心地使用這些控制碼:

  • 最佳做法是呼叫 ObReferenceObjectByHandle,指定正確的 AccessMode (通常來自 Irp-RequestorMode>) 、 DesiredAccessObjectType 參數,例如 IoFileObjectType 或 ExEventObjectType,將控制碼轉換成物件指標。

  • 如果必須直接在呼叫內使用控制碼,最好使用函式的 Nt 變體,而不是函式的 Zw 變體。 這會強制執行參數檢查,並處理作業系統的驗證,因為先前的模式會是 UserMode ,因此不受信任。 請注意,如果前一個模式是 UserMode,則傳遞給指標的 Nt 函式的參數可能會失敗驗證。 Nt 和 Zw 常式會傳回 IoStatusBlock 參數,您應該檢查此參數以確認有無錯誤。

  • 必須適當地捕獲錯誤,並必須視需要使用 __try 和 __except 進行處理。 發生錯誤時,許多快取管理程式 (Cc) 、記憶體管理程式 (Mm) 及檔案系統執行時期程式庫常式 (FsRtl) 都會引發異常狀況。

任何驅動程式都不應該依賴從使用者模式應用程式傳遞的控制碼或參數,而不採取適當的預防措施。

請注意,如果使用 Nt 變體來開啟檔案,則也必須使用 Nt 變體來關閉檔案。