Поделиться через


Использование версий нативных системных сервисных процедур Nt и Zw

API собственных служб операционной системы Windows реализуется как набор подпрограмм, выполняемых в режиме ядра. Эти подпрограммы имеют имена, начинающиеся с префикса 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.

В этом разделе содержатся следующие статьи:

ПредыдущийРежим

библиотек и заголовков

Что означает префикс Zw?

Определение прав доступа

процедуры NtXxx