Собственный API Windows:Когда и зачем использовать вызовы API с префиксом Zw и Nt?

StackOverflow https://stackoverflow.com/questions/4770553

  •  22-10-2019
  •  | 
  •  

Вопрос

В Native API Microsoft экспортирует две версии каждого вызова API: одну с префиксом Zw, а другую с Nt, например.ZwCreateThread и NtCreateThread.

Мой вопрос: в чем разница между этими двумя версиями вызовов, а также когда и почему следует использовать исключительно Zw или Nt?Насколько я понимаю, версия Zw гарантирует, что вызывающая сторона находится в режиме ядра, а Nt - нет.

Меня также интересует конкретное значение префиксов/аббревиатур Zw и Nt?Можно предположить, что Nt, вероятно, относится к семейству Windows NT (новые технологии) или Native (вероятно, нет)?Что касается Zw, это что-то значит?

Это было полезно?

Решение

Обновлять:

Помимо ответа Ларри Остермана (который вы должны определенно Читать), есть еще одна вещь, которую я должен упомянуть:

Поскольку варианты NTXXX выполняют проверки, как если бы вызов поступает из пользовательского режима, это означает, что Любые буферы, передаваемые в функцию NTXXS, должны находиться в адресах пользовательского режима, а не в режиме ядра. Анкет Так что, если вы называете функцию как NtCreateFile В своем драйвере и передайте его указаниям на буферы моды ядра, вы вернете STATUS_ACCESS_VIOLATION из-за этого.


Видеть Использование версий NT и ZW нативных системных служб.

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

Рутины нативных системных услуг делают дополнительные предположения о параметрах, которые они получают. Если подпрограмма получает указатель на буфер, который был выделен драйвером ядра, подпрограмма предполагает, что буфер был выделен в системной памяти, а не в памяти пользователя. Если подпрограмма получает дескриптор, который был открыт приложением пользовательского режима, подпрограмма ищет ручку в таблице ручки пользователя, а не в таблице ручки режима ядра.

Также, Zw Ничего не стоит. Видеть Что означает префикс ZW?:

В подпрограмме «Нативные системы» Windows есть имена, которые начинаются с префиксов NT и ZW. Префикс NT является аббревиатурой Windows NT, но префикс ZW не имеет значения. ZW был выбран частично, чтобы избежать потенциальных конфликтов именования с другими API, и частично, чтобы избежать использования любых потенциально полезных двухбуквенных префиксов, которые могут потребоваться в будущем.

Другие советы

Я собирался оставить это как комментарий к ответу Мерхдада, но получилось слишком долго...

Ответ Мехрдада на 100% точен.Это также немного вводит в заблуждение."Предыдущий режим» Статья, на которую есть ссылка в статье «Использование Nt и Zw...», Мехрдад рассматривает ее более подробно.Перефразируя:Основное различие между вызовами API Nt и Zw заключается в том, что вызовы Zw проходят через диспетчер системных вызовов, но для водителей, Вызовы Nt — это прямые вызовы API.

Когда драйвер вызывает Zw API, единственным реальным эффектом работы через диспетчер системных вызовов является то, что он устанавливает KeGetPreviousMode() в KernelMode вместо UserMode (очевидно, что для кода пользовательского режима формы Zw и Nt идентичны).Когда различные системные вызовы видят, что ExGetPreviousMode имеет значение KernelMode, они обходят проверку доступа (поскольку драйверы могут делать что угодно).

Если драйвер вызывает NT-форму API, возможно, произойдет сбой из-за проверок доступа.

Конкретный пример:если драйвер вызывает NtCreateFile, NtCreateFile вызовет SeAccessCheck(), чтобы проверить, имеет ли приложение, вызвавшее драйвер, разрешения на создание файла.Если тот же драйвер называется ZwCreateFile, вызов API NtCreateFile не будет вызывать SeAccessCheck, поскольку ExGetPreviousMode возвращает KernelMode, и, таким образом, предполагается, что драйвер имеет доступ к файлу.

Авторам драйверов важно понимать разницу между ними, поскольку это может иметь серьезные последствия для безопасности...

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top