В чем разница между ZwOpenFile и NtOpenFile? - PullRequest
1 голос
/ 01 июня 2010

ZWOpenFile и NtOpenFile являются функциями nt dll .. ZwOpenFile реализован так же, как NtopenFile ... но я не понимаю, почему ZWopenFile включен в функцию nt dll. Может кто-нибудь объяснить, пожалуйста, разницу?

Ответы [ 3 ]

3 голосов
/ 01 июня 2010

Это задокументировано в MSDN :

Драйвер режима ядра вызывает Zw-версию собственной подпрограммы системных служб, чтобы сообщить подпрограмме, что параметры поступают из надежного источника режима ядра. В этом случае подпрограмма предполагает, что она может безопасно использовать параметры без предварительной их проверки. Однако, если параметры могут быть из источника пользовательского режима или источника режима ядра, драйвер вместо этого вызывает версию подпрограммы Nt, которая на основе истории вызывающего потока определяет, были ли параметры созданы пользователем режим или режим ядра. Для получения дополнительной информации о том, как процедура отличает параметры пользовательского режима от параметров режима ядра, см. PreviousMode .

В основном это относится к тому, как параметры проверяются.

2 голосов
/ 01 июня 2010

Обычно драйверы ядра должны использовать только функции ZwXxx().

При вызове из пользовательского режима функции ZwXxx() и NtXxx() одинаковы - они разрешают одинаковые биты кода в ntdll.dll.

При вызове из драйвера режима ядра вариант Zwxxx() гарантирует, что флаг, используемый ядром, установлен для указания того, что режим запросчика (что должно указывать на режим вызывающего) является режимом ядра. Если драйвер ядра вызывает вариант NtXxx(), режим запросчика явно не установлен, поэтому он остается один и может указывать режим пользователя или ядра, в зависимости от того, что произошло в стеке вызовов до этого момента.

Если флаг режима запроса установлен в пользовательский режим, ядро ​​проверит параметры, что может быть неправильно, особенно если драйвер ядра передает буферы режима ядра, так как в этом случае проверка не будет выполнена. ), если он установлен в режим ядра, ядро ​​неявно доверяет параметрам.

Таким образом, правила использования этих имен API обычно сводятся к следующему: если вы пишете драйвер ядра, вызовите версию ZwXxx() (если вы не имеете дело с особыми ситуациями, и вы не знаете, что делаете и Зачем). Если вы пишете компонент пользовательского режима, не имеет значения, какой набор вы вызываете.

Насколько я знаю, Microsoft только документирует NtXxx() для использования в пользовательском режиме (где это указывает, что они являются пользовательским режимом, эквивалентным соответствующей функции ZwXxx()).

0 голосов
/ 27 апреля 2015

Дайте пример тому, что уже было сказано, чтобы гарантировать, что ОП или кто-либо еще получат полную картину.

  1. Вызовы NtXxx из пользовательского режима приводят к передаче менее надежных данных (из пользовательского режима) в более привилегированный уровень (режим ядра). Поэтому он ожидает, что буфер имеет действительный адрес пользовательского режима, передаваемые дескрипторы являются допустимыми дескрипторами пользовательского режима и т. Д.

  2. Если драйвер вызывает NtXxx api вместо его эквивалентного ZwXxx, он должен гарантировать, что передаются действительные аргументы пользовательского режима, т.е. он не может передать адрес режима ядра (даже если он действителен) и дескриптор режима ядра ( см. OBJ_KERNEL_HANDLE).

  3. Как уже говорилось, эквивалент ZwXxx API явно указывает (через уровень запросчика), что такая проверка параметров должна быть пропущена, так как вызываемый объект имеет тот же уровень привилегий, что и вызывающий.

Вот ссылка на хорошую отправную точку для тех, кто хочет выйти за рамки очевидного, https://www.osronline.com/article.cfm?id=257.

...