Identificadores de objeto

Os drivers e os componentes do modo de usuário acessam a maioria dos objetos definidos pelo sistema por meio de identificadores. Os identificadores são representados pelo tipo de dados opaco HANDLE. (Observe que os identificadores não são usados para acessar objetos de dispositivo ou objetos de driver.)

Para a maioria dos tipos de objeto, a rotina do modo kernel que cria ou abre o objeto fornece um identificador para o chamador. Em seguida, o chamador usa esse identificador em operações subsequentes no objeto .

Aqui está uma lista de tipos de objeto que os drivers normalmente usam e as rotinas que fornecem identificadores para objetos desse tipo.

Tipo de objeto Rotina de criação/abertura correspondente

Arquivo

IoCreateFile, ZwCreateFile, ZwOpenFile

Chaves do Registro

IoOpenDeviceInterfaceRegistryKey, IoOpenDeviceRegistryKey, ZwCreateKey, ZwOpenKey

Threads

PsCreateSystemThread

Eventos

IoCreateSynchronizationEvent, IoCreateNotificationEvent

Links simbólicos

ZwOpenSymbolicLinkObject

Objetos do diretório

ZwCreateDirectoryObject

Objetos section

ZwOpenSection

Quando o driver não requer mais acesso ao objeto , ele chama a rotina ZwClose para fechar o identificador. Isso funciona para todos os tipos de objeto listados na tabela acima.

A maioria das rotinas que fornecem identificadores usa uma estrutura OBJECT_ATTRIBUTES como parâmetro. Essa estrutura pode ser usada para especificar atributos para o identificador.

Os drivers podem especificar os seguintes atributos de identificador:

  • OBJ_KERNEL_HANDLE

    O identificador só pode ser acessado no modo kernel.

  • OBJ_INHERIT

    Todos os filhos do processo atual recebem uma cópia do identificador quando são criados.

  • OBJ_FORCE_ACCESS_CHECK

    Esse atributo especifica que o sistema executa todas as verificações de acesso no identificador. Por padrão, o sistema ignora todas as verificações de acesso em identificadores criados no modo kernel.

Use a rotina InitializeObjectAttributes para definir esses atributos em uma estrutura OBJECT_ATTRIBUTES .

Para obter informações sobre como validar identificadores de objeto, consulte Falha ao validar identificadores de objeto.

Identificadores de objeto privado

Sempre que um driver cria um identificador de objeto para seu uso privado, o driver deve especificar o atributo OBJ_KERNEL_HANDLE. Isso garante que o identificador esteja inacessível para aplicativos no modo de usuário.

Identificadores de objeto compartilhado

Um driver que compartilha identificadores de objeto entre o modo kernel e o modo de usuário deve ser cuidadosamente gravado para evitar a criação acidental de falhas de segurança. Aqui estão algumas diretrizes:

  1. Crie identificadores no modo kernel e passe-os para o modo de usuário, em vez do contrário. Identificadores criados por um componente de modo de usuário e passados para o driver não devem ser confiáveis.

  2. Se o driver precisar manipular identificadores em nome de aplicativos de modo de usuário, use o atributo OBJ_FORCE_ACCESS_CHECK para verificar se o aplicativo tem o acesso necessário.

  3. Use ObReferenceObjectByPointer para manter uma referência de modo kernel em um identificador compartilhado. Caso contrário, se um componente do modo de usuário fechar o identificador, a contagem de referências será zero e, se o driver tentar usar ou fechar o identificador, o sistema falhará.

Se um aplicativo de modo de usuário criar um objeto de evento, um driver poderá aguardar com segurança que esse evento seja sinalizado, mas somente se o aplicativo passar um identificador para o objeto de evento para o driver por meio de um IOCTL. O driver deve manipular o IOCTL no contexto do processo que criou o evento e deve validar se o identificador é um identificador de evento chamando ObReferenceObjectByHandle.