Identificadores de objeto
Los controladores y los componentes en modo de usuario acceden a la mayoría de los objetos definidos por el sistema a través de identificadores. Los identificadores se representan mediante el tipo de datos opaco HANDLE. (Tenga en cuenta que los identificadores no se usan para acceder a objetos de dispositivo o objetos de controlador).
Para la mayoría de los tipos de objeto, la rutina en modo kernel que crea o abre el objeto proporciona un identificador al autor de la llamada. A continuación, el autor de la llamada usa ese identificador en operaciones posteriores en el objeto .
Esta es una lista de tipos de objeto que suelen usar los controladores y las rutinas que proporcionan identificadores a objetos de ese tipo.
Tipo de objeto | Rutina de creación y apertura correspondientes |
---|---|
Archivo |
|
Claves del Registro |
IoOpenDeviceInterfaceRegistryKey, IoOpenDeviceRegistryKey, ZwCreateKey, ZwOpenKey |
Subprocesos |
|
Eventos |
|
Vínculos simbólicos |
|
Objetos de directorio |
|
Objetos de sección |
Cuando el controlador ya no requiere acceso al objeto, llama a la rutina ZwClose para cerrar el identificador. Esto funciona para todos los tipos de objeto enumerados en la tabla anterior.
La mayoría de las rutinas que proporcionan identificadores toman una estructura OBJECT_ATTRIBUTES como parámetro. Esta estructura se puede usar para especificar atributos para el identificador.
Los controladores pueden especificar los siguientes atributos de identificador:
OBJ_KERNEL_HANDLE
Solo se puede acceder al identificador desde el modo kernel.
OBJ_INHERIT
Todos los elementos secundarios del proceso actual reciben una copia del identificador cuando se crean.
OBJ_FORCE_ACCESS_CHECK
Este atributo especifica que el sistema realiza todas las comprobaciones de acceso en el identificador. De forma predeterminada, el sistema omite todas las comprobaciones de acceso en los identificadores creados en modo kernel.
Use la rutina InitializeObjectAttributes para establecer estos atributos en una estructura de OBJECT_ATTRIBUTES .
Para obtener información sobre cómo validar los identificadores de objeto, vea Error al validar identificadores de objeto.
Identificadores de objeto privado
Cada vez que un controlador crea un identificador de objeto para su uso privado, el controlador debe especificar el atributo OBJ_KERNEL_HANDLE. Esto garantiza que el identificador no sea accesible para las aplicaciones en modo de usuario.
Identificadores de objeto compartidos
Un controlador que comparte controladores de objetos entre el modo kernel y el modo de usuario debe escribirse cuidadosamente para evitar la creación accidental de agujeros de seguridad. Estas son algunas directrices:
Cree identificadores en modo kernel y páselos al modo de usuario, en lugar del revés. Los identificadores creados por un componente en modo de usuario y pasados al controlador no deben ser de confianza.
Si el controlador debe manipular los identificadores en nombre de las aplicaciones en modo de usuario, use el atributo OBJ_FORCE_ACCESS_CHECK para comprobar que la aplicación tiene el acceso necesario.
Use ObReferenceObjectByPointer para mantener una referencia en modo kernel en un identificador compartido. De lo contrario, si un componente en modo de usuario cierra el identificador, el recuento de referencias va a cero y, si el controlador intenta usar o cerrar el identificador, el sistema se bloqueará.
Si una aplicación en modo de usuario crea un objeto de evento, un controlador puede esperar de forma segura a que se señale ese evento, pero solo si la aplicación pasa un identificador al objeto de evento al controlador a través de un IOCTL. El controlador debe controlar el IOCTL en el contexto del proceso que creó el evento y debe validar que el identificador es un identificador de eventos llamando a ObReferenceObjectByHandle.