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


Хэндлы объектов

Драйверы и компоненты пользовательского режима обращаются к большинству системных объектов с помощью дескрипторов. Дескриптор представлен непрозрачным типом данных HANDLE. (Обратите внимание, что дескрипторы не используются для доступа к объектам устройства или объектам драйвера.)

Для большинства типов объектов подпрограмма в режиме ядра, которая создает или открывает объект, предоставляет дескриптор вызывающему. Затем вызывающая сторона использует этот дескриптор в последующих операциях с объектом.

Вот список типов объектов, которые драйверы часто используют, и подпрограмм, которые предоставляют идентификаторы объектам этого типа.

Тип объекта Соответствующая процедура создания и открытия

Файл

IoCreateFile, ZwCreateFile, ZwOpenFile

Ключи реестра

IoOpenDeviceInterfaceRegistryKey, IoOpenDeviceRegistryKey, ZwCreateKey, ZwOpenKey

Потоки

PsCreateSystemThread

События

IoCreateSynchronizationEvent, IoCreateNotificationEvent

Символические связи

ZwOpenSymbolicLinkObject

Объекты каталога

ZwCreateDirectoryObject

Объекты раздела

ZwOpenSection

Если драйвер больше не требует доступа к объекту, он вызывает подпрограмму ZwClose , чтобы закрыть дескриптор. Это работает для всех типов объектов, перечисленных в таблице выше.

Большинство подпрограмм, которые предоставляют дескрипторы, используют структуру OBJECT_ATTRIBUTES в качестве параметра. Эта структура может использоваться для задания атрибутов дескриптора.

Драйверы могут задать следующие атрибуты дескриптора:

  • OBJ_KERNEL_HANDLE

    Доступ к дескриптору возможен только в режиме ядра.

  • OBJ_INHERIT

    Все дочерние элементы текущего процесса получают копию дескриптора при создании.

  • OBJ_FORCE_ACCESS_CHECK

    Этот атрибут указывает, что система выполняет все проверки доступа на дескриптор. По умолчанию система обходит все проверки доступа на дескрипторах, созданных в режиме ядра.

Используйте подпрограмму InitializeObjectAttributes , чтобы задать эти атрибуты в структуре OBJECT_ATTRIBUTES .

Сведения о проверке дескрипторов объектов см. в разделе "Сбой проверки дескрипторов объектов".

Дескриптор частных объектов

Всякий раз, когда драйвер создает дескриптор объекта для частного использования, драйвер должен указать атрибут OBJ_KERNEL_HANDLE. Это гарантирует, что дескриптор недоступен для приложений пользовательского режима.

Дескриптор общих объектов

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

  1. Создайте дескрипторы в режиме ядра и передайте их в пользовательский режим, вместо обратного. Дескрипторы, созданные компонентом пользовательского режима и переданные драйверу, не следует считать надежными.

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

  3. Используйте ObReferenceObjectByPointer , чтобы сохранить ссылку на режим ядра в общем дескрипторе. В противном случае, если компонент пользовательского режима закрывает дескриптор, число ссылок уменьшается до нуля, и если драйвер затем пытается использовать или закрыть дескриптор, то система завершится сбоем.

Если приложение в пользовательском режиме создает объект события, драйвер может безопасно ждать передачи этого события, но только если приложение передает дескриптор объекту события драйверу через IOCTL. Драйвер должен обрабатывать IOCTL в контексте процесса, создавшего событие, и должен проверить, является ли дескриптор дескриптором события, вызвав ObReferenceObjectByHandle.