Дескрипторы объектов
Драйверы и компоненты пользовательского режима получают доступ к большинству системных объектов через дескрипторы. Дескрипторы представлены непрозрачным типом данных HANDLE. (Обратите внимание, что дескрипторы не используются для доступа к объектам устройств или объектам драйвера.)
Для большинства типов объектов подпрограмма режима ядра, которая создает или открывает объект, предоставляет дескриптор вызывающей объекту. Затем вызывающий объект использует этот дескриптор в последующих операциях с объектом .
Ниже приведен список типов объектов, которые обычно используются драйверами, и подпрограмм, предоставляющих дескрипторы для объектов этого типа.
Тип объекта | Соответствующая процедура создания и открытия |
---|---|
File |
|
Разделы реестра |
IoOpenDeviceInterfaceRegistryKey, IoOpenDeviceRegistryKey, ZwCreateKey, ZwOpenKey |
Потоки |
|
События |
|
Символические связи |
|
Объекты каталога |
|
Объекты Section |
Когда драйверу больше не требуется доступ к объекту, он вызывает подпрограмму ZwClose , чтобы закрыть дескриптор. Это подходит для всех типов объектов, перечисленных в таблице выше.
Большинство подпрограмм, предоставляющих дескрипторы, принимают в качестве параметра структуру OBJECT_ATTRIBUTES . Эту структуру можно использовать для указания атрибутов дескриптора.
Драйверы могут указывать следующие атрибуты дескриптора:
OBJ_KERNEL_HANDLE
Доступ к дескриптором можно получить только из режима ядра.
OBJ_INHERIT
Все дочерние элементы текущего процесса получают копию дескриптора при их создании.
OBJ_FORCE_ACCESS_CHECK
Этот атрибут указывает, что система выполняет все проверки доступа к дескриптором. По умолчанию система обходит все проверки доступа для дескрипторов, созданных в режиме ядра.
Используйте подпрограмму InitializeObjectAttributes , чтобы задать эти атрибуты в OBJECT_ATTRIBUTES структуре.
Сведения о проверке дескрипторов объектов см. в разделе Сбой проверки дескрипторов объектов.
Дескрипторы частных объектов
Всякий раз, когда драйвер создает дескриптор объекта для частного использования, драйвер должен указать атрибут OBJ_KERNEL_HANDLE. Это гарантирует, что дескриптор будет недоступен для приложений в пользовательском режиме.
Дескрипторы общих объектов
Драйвер, который использует дескрипторы объектов в режиме ядра и режиме пользователя, должен быть тщательно написан, чтобы избежать случайного создания бреш в системе безопасности. Ниже приведены некоторые рекомендации.
Создайте дескриптор в режиме ядра и передайте их в пользовательский режим, а не наоборот. Дескрипторам, созданным компонентом пользовательского режима и переданным драйверу, не следует доверять.
Если драйвер должен управлять дескрипторами от имени приложений в пользовательском режиме, используйте атрибут OBJ_FORCE_ACCESS_CHECK, чтобы убедиться, что приложение имеет необходимый доступ.
Используйте ObReferenceObjectByPointer , чтобы сохранить ссылку на режим ядра в общем дескрипторе. В противном случае, если компонент пользовательского режима закроет дескриптор, количество ссылок будет равно нулю, а если драйвер попытается использовать или закрыть дескриптор, система аварийно завершит работу.
Если приложение пользовательского режима создает объект события, драйвер может безопасно ожидать передачи сигнала об этом событии, но только в том случае, если приложение передает дескриптор объекта события драйверу через IOCTL. Драйвер должен обрабатывать IOCTL в контексте процесса, создавшего событие, и должен проверить, является ли дескриптор дескриптором события, вызвав ObReferenceObjectByHandle.