Собственный API Windows: когда и почему используются вызовы API с префиксом Zw vs Nt? - PullRequest
10 голосов
/ 23 января 2011

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

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

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

Ответы [ 2 ]

12 голосов
/ 23 января 2011

Обновление:

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

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


См. Использование Ntи версии Zw подпрограмм собственных системных служб .

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

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

Кроме того,Zw ничего не значит.См. Что означает префикс Zw? :

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

11 голосов
/ 23 января 2011

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

Ответ Мердада точен на 100%.Это также немного вводит в заблуждение.Статья " PreviousMode ", на которую ссылается статья "Использование 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, и, следовательно, предполагается, что драйвер имеет доступ к файлу.

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

...