使用原生系統服務常式的 Nt 和 Zw 版本
Windows 原生作業系統服務 API 會實作為一組在核心模式中執行的常式。 這些常式具有開頭為 Nt 或 Zw前置詞的名稱。 核心模式驅動程式可以直接呼叫這些常式。 使用者模式應用程式可以使用系統呼叫來存取這些常式。
除了一些例外狀況,每個原生系統服務常式都有兩個稍微不同的版本,其名稱類似,但前置詞不同。 例如,對 NtCreateFile 和 ZwCreateFile 的呼叫會執行類似的作業,事實上,由相同的核心模式系統常式提供服務。 對於來自使用者模式的系統呼叫,常式的 Nt 和 Zw 版本的行為相同。 針對核心模式驅動程式的呼叫,常式的 Nt 和 Zw 版本會因如何處理呼叫端傳遞至常式的參數值而有所不同。
核心模式驅動程式會呼叫原生系統服務常式的 Zw 版本,以通知常式參數來自受信任的核心模式來源。 在此情況下,常式假設它可以安全地使用參數,而不需要先驗證參數。 不過,如果參數可能是來自使用者模式來源或核心模式來源,則驅動程式會改為呼叫 Nt 版本的常式,根據呼叫執行緒的歷程記錄來判斷參數是否源自使用者模式或核心模式。 如需常式如何區分使用者模式參數與核心模式參數的詳細資訊,請參閱 PreviousMode。
當使用者模式應用程式呼叫原生系統服務常式的 Nt 或 Zw 版本時,常式一律會將它收到的參數視為來自不受信任之使用者模式來源的值。 常式會先徹底驗證參數值,再使用 參數。 特別是,常式會探查任何呼叫端提供的緩衝區,以確認緩衝區位於有效的使用者模式記憶體中,並正確對齊。
原生系統服務常式會針對其接收的參數進行其他假設。 如果常式收到核心模式驅動程式所配置的緩衝區指標,則常式會假設緩衝區已配置於系統記憶體中,而不是在使用者模式記憶體中。 如果常式收到由使用者模式應用程式開啟的控制碼,常式會在使用者模式控制碼資料表中尋找控制碼,而不是在核心模式控制碼資料表中。
在少數情況下,參數值的意義在使用者模式和核心模式的呼叫之間會有所差異。 例如, ZwNotifyChangeKey 常式 (或其 NtNotifyChangeKey 對應) 有一對輸入參數 ApcRoutine 和 ApcCoNtext,這表示不同的專案,視參數來自使用者模式或核心模式來源而定。 針對使用者模式的呼叫, ApcRoutine 會指向 APC 常式, 而 ApcCoNtext 會指向作業系統在呼叫 APC 常式時所提供的內容值。 針對核心模式的呼叫, ApcRoutine 會指向 WORK_QUEUE_ITEM 結構, 而 ApcCoNtext 會指定 WORK_QUEUE_ITEM 結構所描述的工作佇列專案類型。
本節包含下列主題: