使用 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 結構所描述的工作佇列項目類型。
本節包含下列主題: