ZWOpenFile и NtOpenFile являются функциями nt dll..ZwOpenFile реализована так же, как и NtopenFile .. но я не понимаю, почему ZWopenFile включен в функцию dll dll. Кто-нибудь может объяснить мне разницу?В чем разница между ZwOpenFile и NtOpenFile?
ответ
Это documented in MSDN:
драйвер режима ядра вызывает версию Zw нативного рутина системных служб, чтобы сообщить программе, что параметры поступают из доверенного источника, в режиме ядра. В этом случае процедура предполагает, что она может безопасно использовать параметры без их первой проверки. Однако, если параметры могут быть либо из источника пользовательского режима, либо из источника в режиме ядра, вместо этого драйвер вместо Nt-версии подпрограммы определяет, на основе истории вызывающего потока, параметры, возникшие у пользователя режим или режим ядра. Для получения дополнительной информации о том, как процедура различает параметры пользовательского режима из параметров режима ядра, см. PreviousMode.
В основном это относится к тому, как параметры проверяются.
Как правило, драйверы ядра должны использовать только функции ZwXxx()
.
При вызове из пользовательского режима функции ZwXxx()
и NtXxx()
являются точно такими же - они разрешают одни и те же коды кода в файле ntdll.dll.
При вызове из драйвера режима ядра вариант Zwxxx()
гарантирует, что флаг, используемый ядром, установлен, чтобы указать, что режим запроса (то, что должен указывать режим звонящего) - это режим ядра. Если драйвер ядра вызывает вариант NtXxx()
, режим запроса не задан явно, поэтому он остается один и может указывать режим пользователя или ядра, в зависимости от того, что произошло в стеке вызовов до этой точки.
Если флаг режима запроса установлен в пользовательский режим, ядро будет проверять параметры, что может оказаться неправильным (особенно если драйвер ядра передается в буферах режима ядра, поскольку проверка не будет выполнена в этом случае case), если он установлен в режим ядра, ядро неявно доверяет параметрам.
Таким образом, правила использования этих имен API обычно сводятся к следующему: если вы пишете драйвер ядра, позвоните по номеру ZwXxx()
(если вы не имеете дело со специальными ситуациями, и вы знаете, что делаете и почему). Если вы пишете компонент пользовательского режима, не имеет значения, какой набор вы вызываете.
Насколько я знаю, Microsoft только документирует NtXxx()
для использования в пользовательском режиме (где он указывает, что они эквивалентны пользовательскому режиму для соответствующей функции ZwXxx()
).
Дайте пример тому, что уже было сказано, чтобы гарантировать, что OP или кто-либо еще получит полную картину.
NtXxx вызовы из пользовательского режима приводит попутно менее надежные данные (из пользовательского режима) в более привилегированный слой (режим ядра). Поэтому он ожидает, что буфер имеет действительный адрес режима пользователя, переданные Ручки являются действительными ручками режима пользователя и т. Д.
Если драйвер вызывает NtXxx api вместо его эквивалентного ZwXxx, он должен убедиться, что действительные аргументы режима пользователя что он не может передать адрес режима ядра (даже если он действителен) и дескриптор режима ядра (см. OBJ_KERNEL_HANDLE).
Как уже говорилось, эквивалент API ZwXxx явно указывает (через уровень запрашивающего), что такая проверка параметров должна быть пропущена, поскольку вызываемый пользователь имеет тот же уровень привилегий, что и вызывающий.
Вот ссылка на хорошую отправную точку для тех, кто хочет выйти за рамки очевидных, https://www.osronline.com/article.cfm?id=257.