El Registro: organización

Como una vista esencial y panorámica, diremos que el registro está compuesto de 5 llaves raíz y de ellas las HKLM y HKU son más importantes que el resto. Son las llaves que Windows guarda en disco, mientras que el resto son enlaces a sub-llaves de una u otra. HKCU es un enlace a una sub-llave de HKU, HKCR y HKCC son enlaces a sub-llaves de HKLM.

registro03

Las configuraciones pueden ser para el usuario o para el equipo. En la llave HKCU tenemos los de usuarios y en la HKLM la del equipo.

HKEY_USERS

Aquí nos encontramos al menos con:

  • .DEFAULT
    • Configuración por usuario que usa Windows para mostrar el escritorio antes de que cualquier usuario inicie sesión. No es lo mismo que el perfil predeterminado, que utiliza Windows para crear la configuración de los usuarios la primera vez que inician sesión en el equipo.
  • SID
    • Donde SID es el identificador de seguridad de la consola de usuario, contiene configuración por usuario. HKCU enlaza con esta llave. Valores de preferencia de escritorio de usuario, configuración de Panel de control, etc…
  • SID_classes
    • Donde SID, al igual que el anterior es el identificador de seguridad de la consola de usuario, contiene configuración por usuario, registro de clases y asociaciones de archivos. Windows mezcla los contenidos de HKLMSOFTWAREClasses y HKUSID_Classes en HKCR.

Suelen verse otros SID en HKU, como los SID conocidos: s-1-5-18, s-1-5-19, s-1-5-20, etc…

Cualquier otra sub-llave pertenece a usuarios secundarios, es decir, si usamos el comando RunAs para ejecutar algún programa como usuario distinto.

registro04

HKEY_CURRENT_USER

Aquí encontramos la configuración por usuario de la consola del usuario. Esta llave raíz está enlazada a HKUSID (El SID representa cada identificador de usuario). Esta rama incluye las variables de entorno, configuración del escritorio, conexiones de red, impresoras, y preferencias de las aplicaciones.

Así a bote pronto:

  • AppEvents
    • Sonidos asociados con eventos.
  • Console
    • Almacena datos del subsistema de consola, que almacena todos modos caracteres de aplicaciones, incluido el prompt de MS-DOS. La llave Console puede contener sub-llaves de ventanas de comando personalizadas.
  • Control Panel
    • Configuración de la apariencia del escritorio, configuración de accesibilidad y la configuración regional. Muchos de estos valores se configuran desde el Panel de Control, sin embargo dentro de esta llave hay un montón de configuraciones útiles que carecen de interfaz de usuario; que sólo podemos configurar mediante el registro.
  • Environment
    • Variables de entorno establecidas por los usuarios. Los valores predeterminados se encuentran en el perfil del usuario.
  • Identities
    • Una sub-llave por cada identidad de Outlook express. Desde la compatibilidad de Windows con perfiles múltiples de usuario, las configuraciones de cada uno van separadas, por lo que esta clave se usa ya pocas veces.
  • Keyboard Layout
    • Información sobre los teclados instalados.
  • Network
    • Información sobre las unidades de red. Cada sub-llave dentro de Network es una unidad de red, conteniendo su configuración a usar para reconexión.
  • Printers
    • Preferencias de usuario de impresoras.
  • Software
    • Configuraciones de aplicación por usuario. Windows tiene muchas de sus configuraciones dentro de esta llave.
  • Volatile Environment
    • Variables de entorno definidas dentro de la sesión de usuario.

HKEY_LOCAL_MACHINE

Esta llave raíz contiene los valores por equipo, que significa que la configuración establecida aquí es de aplicación al equipo y afectará a cada usuario que inicie sesión en el.

  • HARDWARE
    • Descripción del hardware que Windows detecta e inicia. Esta llave se crea cada vez que el sistema operativo inicia, incluyendo la información sobre dispositivos, sus controladores y recursos asociados.
  • SAM
    • Base de datos de Seguridad Local de Windows, el Administrador de cuentas de Seguridad (SAM), donde Windows almacena usuarios y grupos. Las listas de control de acceso de esta llave (ACL) impiden verla, aun siendo administrador. Es un enlace a la llave HKLMSECURITYSAM
  • SECURITY
    • Contenido de la sub-llave SAM y algunos otros valores de seguridad. La ACL impide verla, a menos que hagamos por verla, claro.
  • SOFTWARE
    • Configuraciones de las aplicaciones por equipo. Windows también almacena configuraciones propias aquí.
  • SYSTEM
    • Contiene conjuntos de control, del que uno será el actual. Los conjuntos quedan disponibles para su uso por Windows. Cada sub-llave se llama ControlSet???, donde ??? es un número que se incrementa y que comienza por 001. El sistema operativo mantiene al menos dos conjuntos de control para asegurarse que puede iniciarse correctamente siempre. Estos conjuntos contienen configuraciones de servicios y controladores de dispositivo. HKLMSYSTEMCUrrentControlSet es un enlace a ControlSet???, y HKLMSYSTEMSelect al ControlSet??? en uso.

HKEY_CLASSES_ROOT

Aquí se esconden dos tipos de configuración. La primera de ellas es la asociación de archivos, que asocia los distintos tipos de archivo con los programas que pueden abrirlos, editarlos, imprimirlos. La segunda es el registro de clases para los objetos COM. Esta es una de las llaves más interesantes del registro a personalizar, nos permite cambiar el comportamiento del sistema operativo. Es la más grande además, por lo que consume la mayor parte del espacio del registro. Ha sufrido algunos cambios desde Windows 2000, realizando una mezcla de llaves que se supone que son beneficiosos, como:

  • Los programas pueden registrar su asociación de archivo y clase tanto por usuario como por equipo.
  • Distintos usuarios que comparten el equipo pueden estar utilizando diferentes programas para editar el mismo tipo de archivo, sin que ello afecte a ninguno de ellos.
  • Debido a que el registro de clases y asociaciones de archivo por usuario están en el perfil de usuario, le siguen a cualquier equipo al usar perfiles móviles.
  • Podemos limitar el acceso a HKLMSOFTWAREClasses sin impedir a los usuarios cambiar HKCUSoftwareClasses, ganando en seguridad en el registro sin consecuencias en la posibilidad de que los usuarios cambien las asociaciones.

HKEY_CURRENT_CONFIG

Enlace a los datos de configuración del perfil actual de hardware, HKLMSYSTEMCurrentControlSetHardware Profiles****, donde **** es un número incremental desde el 0000.

El Registro: estructura

La estructura del registro de Windows es muy parecida a la estructura del sistema de archivos:

 

registro explorador

 

En el editor del registro (ya charlaremos sobre el), se muestra en el árbol de la izquierda, panel de llaves, la jerarquía del registro. Aquí cada carpeta es una llave del registro. A la derecha, panel de valores, observamos los valores de las llaves. El explorador de Windows nos muestra también la jerarquía de carpetas y los valores en dos paneles.

Llaves

Las llaves son similares a las carpetas ya que tienen las mismas reglas de nombrado. Podemos anidar una o más llaves dentro de otra llave, mientras sus nombres sean únicos dentro de cada llave. El nombre está limitado a 512 caracteres ANSI o 256 Unicode y podemos usar cualquier carácter ASCII que no sea la barra invertida , el asterisco *, y la interrogación ?. Windows se reserva todos los nombres que comienzan con un periodo para su propio uso.

Las similitudes entre el registro y el sistema siguen con las rutas. La ruta C:WindowsSystem32notepad.exe se refiere al archivo Notepad.exe en la unidad C, carpeta Windows, subcarpeta System32. La ruta HKLMSystemCurrentControlSetControlCurrentUser se refiere al valor CurrentUser de la llave raíz HKLM, que se encuentra en la subllave Control de la subllave de SYSTEM llamada CurrentControlSet. Notación de nombre cualificado con el que frecuentemente nos referiremos a una llave y todas sus subllaves como una RAMA.

Como punto a tener en cuenta me referiré a las llaves enlazadas. Windows almacena perfiles de hardware en la RAMA HKLMSYSTEMCurrentControlSetHardware Profiles, cada perfil es una subllave xxxx, donde xxxx es un número incremental que comienza por 0000. La subllave Current es un enlace a toda llave que actualmente se encuentre en los perfiles de hardware, y la llave Raíz HKCC es un enlace a Current.

registro02 

Valores

Cada llave contiene uno o más valores. El nombre de un valor es parecido al nombre de un archivo. El tipo de un valor es similar a la extensión de un archivo, que es lo que indica su tipo. Los datos del valor es parecido al contenido actual del archivo. Si pulsamos en una llave del registro en el panel de llaves del editor, el panel de valores nos mostrará los pertenecientes a dicha llave. En el panel de valores observamos tres columnas, correspondientes a tres partes de un valor:

  • Nombre. Todo valor tiene un nombre. Con las restricciones ya comentadas. Dentro de cada llave ese nombre será único, pudiendo usar el mismo nombre en distintas llaves.
  • Tipo. Cada tipo de valor determina el tipo de dato que puede contener. REG_DWORD un número double-word, REG_SZ una cadena, etc…
  • Datos. Cada valor puede estar vacio, nulo o puede contener datos. Los datos se limitan a 32767 bytes, aunque el límite práctico son 2KB. Los datos se corresponden con su tipo, exceptuando los valores binarios que pueden contener cadenas, doble-words, o cualquier otro.

Cada llave contiene al menos un valor, el valor predeterminado. Casi siempre una cadena, pero algunos programas lo cambian por otros tipos. En muchos casos el valor predeterminado es NULL y el editor nos indica ‘valor no establecido’.

Tipos

  • REG_BINARY
    • Datos binarios, se muestran en hexadecimal y se introducen datos binarios en hexadecimal.
  • REG_DWORD
    • Valores doble-word de 32 bits. Muchos son banderas booleanas (si o no). Valores de tiempo en milisegundos. Números de 32-bits, firmados o no (hay unos rangos). Los valores se ven en decimal o hexadecimal.
  • REG_DWORD_BIG_ENDIAN
    • Orden de los bytes Big_Endian
  • REG_DWORD_LITTLE_ENDIAN
    • Orden de los bytes Little-Endian
  • REG_EXPAND_SZ
    • Texto de longitud variable. Puede incluir variables de entorno que se expandirán luego por el programa antes de su uso.
  • REG_FULL_RESOURCE_DESCRIPTOR
    • Lista de recursos para un dispositivo o controlador de dispositivo. Importante para el Pinchar y Listo P&P.
  • REG_LINK
    • Enlace. No los podemos crear nosotros.
  • REG_MULTI_SZ
    • Valores binarios que contienen listas de cadenas. El editor muestra una cadena por cada línea y nos permite editarlas. Un carácter nulo 0x00 separa cada cadena y dos nulos el final de la lista.
  • REG_ONE
    • Sin tipo definido
  • REG_QWORD
    • Quadruple-word (64 bits).
  • REG_QWORD_BIG_ENDIAN
    • Quadruple-word (64 bits). Como Big_Endian.
  • REG_QWORD_LITTLE_ENDIAN
    • Quadruple-word (64 bits). Como Little-Endian.
  • REG_RESOURCE_LIST
    • Lista de los valores de REG_FULL_RESOURCE_DESCRIPTOR. El editor nos deja verlos pero no editarlos.
  • REG_RESOURCE_REQUERIMENTS_LIST
    • Lista de recursos que un dispositivo necesita. No podemos editarlo.
  • REG_SZ
    • Texto de longitud fija. Es el más común, otro valor REG_DWORD. La cadena termina con un carácter nulo y los programas no expanden las variables de entorno contenidas en valores RG_SZ.

De todos los valores del registro, el valor binario es el menos sencillo. Cuando una aplicación lee un valor binario desde el registro, descifrar su contenido le corresponde a ese programa. Esto significa que las aplicaciones pueden almacenar datos en valores binarios usando sus propias estructuras de datos, que no significan nada para nosotros u otros programas. También, las aplicaciones, frecuentemente, almacenan datos REG_DWORD y REG_SZ en REG_BYNARY, lo que dificulta su búsqueda y descifrado.

Ahora se complica, el registro en la actualidad almacena todos los valores como valores binarios. Las API del registro identifican cada tipo de valor mediante un número, al que los programadores se refieren como constante, y que se tiende a denominar como el número de tipo.

Número

Tipo

0 REG_ONE
1 REG_SZ
2 REG_EXPAND_SZ
3 REG_BINARY
4 REG_DWORD
4 REG_DWORD_LITTLE_ENDIAN
5 REG_DWORD_BIG_ENDIAN
6 REG_LINK
7 REG_MULTI_SZ
8 REG_RESOURCE_LIST

El alma de Windows: el registro

Recuerdos

La configuración en MS-DOS se componía de los archivos config.sys y autoexec.bat.

El primero cargaba los controladores de los dispositivos, mientras que el segundo se encargaba de ejecutar programas, establecer las variables de entorno, y algo más, para preparar el uso de MS-DOS.

Cada aplicación era responsable de sí misma, así como de su configuración.

Obviamente ninguno de estos archivos sirve en Windows.

Windows 3.0 fue el primero que introdujo los archivos INI de configuración, que no eran sino simples archivos de texto con una o varias secciones y, en cada una, uno o varios valores de configuración. Uno de sus contras era carecer de jerarquía y además almacenar valores binarios era engorroso, aunque posible, y el almacenamiento de valores no tenía un estándar para tipos similares de configuración. Relación entre aplicaciones y el sistema operativo fatal y el caso es que cada aplicación tenía su propio INI.

En Windows 3.1 apareció el registro como una herramienta de almacenamiento de configuraciones OLE, mientras que Windows 95/NT 3.5 lo extendieron a una base de datos que al fin y al cabo, es la que Windows XP o Windows 2003 usan. A pesar de que los INI ya no son necesarios, las aplicaciones ahora tienen un camino mucho mejor donde almacenar su configuración, siempre encontraremos varios archivos INI desperdigados en cualquier equipo.

 

Tópicos

Aun con todos sus beneficios, el registro de Windows es una paradoja. Por una parte, un lugar centralizado para todos los datos de configuración de Windows. La piedra angular. De otra parte, el hecho de que el registro sea tan importante también hace que sea una de las debilidades del sistema operativo. Quita la piedra angular y el castillo se derrumba. Si el registro falla, el sistema falla. Afortunadamente un fallo total es menos probable a que me toque la lotería y un fallo parcial que impida el inicio del equipo es fácil de superar.

EL papel de piedra angular del registro es una de las razones de su cariz mítico. Microsoft no ha hablado mucho sobre él. No tenemos un editor en el menú de inicio, encontramos poca información en la ayuda, carecemos de documentos que nos enseñen sus secretos. Parece que sea mágico, y la verdad es que no deja de ser simplemente la configuración del equipo.

Las advertencias que nos encontramos a montones en los lugares donde se hallan instrucciones para editarlo son definitivamente exageradas. Hay poco daño que podamos causarle y que no pueda recuperarse tomando las mínimas precauciones (tener una copia en lugar seguro :-)).

 

A tener claro

Las cosas que deberíamos conocer para trabajar eficientemente con el registro, por ejemplo, familiarizarnos con la notación hexadecimal, conversión hexadecimal-binario y hexadecimal-decimal, GUIDs, Unicode contra ANSI, etc…

Identificadores de seguridad

Cuentas de equipo y usuarios, grupos y otros objetos relacionados con la seguridad son Objetos principales de seguridad. Los Identificadores de Seguridad o SID identifican inequívocamente a los objetos principales de seguridad. Cada vez que Windows y Directorio Activo crean un objeto principal de seguridad le generan un SID. LSA (Local Security Authority) genera los SID para objetos principales locales y entonces los almacena en su base de datos de seguridad local. Domain Security Authority genera los SID para los objetos principales de seguridad del dominio y los almacena en AD. Los SID son únicos dentro de su ámbito. Cada SID local es único en el equipo, como cada SID de dominio lo es dentro del dominio. Windows nunca reusa un SID, o sea, aunque se elimine un objeto principal. De hecho si borramos una cuenta y la volvemos a crear ésta tendrá un nuevo SID.

Es importante recordar que cada cuenta dispone de un SID. Es como tener un número de DNI que te identifica inequívocamente en tu país. Podemos referirnos a una cuenta por su nombre o por su SID, aunque en la práctica rara vez usamos el SID. En el registro veremos frecuentemente los SID de cuenta, por ello la necesidad de familiarizarse sobre ello.

Un SID de ejemplo S-1-5-21-224257856-4948505641-1666550967-500. Los SID siempre comienzan con s-. El número siguiente identifica la versión del SID (aquí versión 1). Luego un número indicando la autoridad de identificación y que normalmente es 5, NT Authority en es caso. La cadena de números siguiente hasta 500 es el identificador de dominio, el resto es un identificador relativo, que es la cuenta o grupo. Esto es una aproximación al formato del SID, cuya complejidad es superior a este breve ejemplo.

Algunos SID son más cortos que en el ejemplo, son los SID conocidos y son los mismos en cada equipo y dominio. Son interesantes porque aparecen una y otra vez tanto en el registro como en otras partes.

SID conocidos

Identificadores globales únicos

Los identificadores globales únicos, más conocidos como GUIDs, son números que identifican objetos inequívocamente como equipos, componentes de programa y dispositivos. Estos objetos a menudo tienen nombre, pero sus GUID permanecen de forma única aun si dos objetos tienen el mismo nombre o si se les cambia el nombre. En otras palabras, un GUID es similar a un SID. Hay muchos GUID en el registro.

Todos tienen el mismo formato. Son números hexadecimales en grupos de 8,4 ,4, 4 y 12 dígitos (del 0-9 y de la A-F). Un guión divide cada grupo de dígitos, y las llaves {}  engloban al número entero. Por ejemplo: {645FF040-5081-101B-9F08-00AA002F954E}, que representa el objeto de papelera que vemos en el escritorio.

Los desarrolladores usan Guidgen.exe para crear GUIDs, pero Windows los genera también. A pesar del origen, Windows garantiza que los GUID son globalmente únicos. No hay que preocuparse de cuantas veces se generan los GUID, el resultado es siempre único. Por eso los GUID son perfectos para identificar equipos y dispositivos.

Notación hexadecimal

El 99% de los datos que se ven en el registro están en notación hexadecimal. Los equipos usan notación hexadecimal más que la decimal por una buena razón, que se comprenderá rápidamente. Saber leer y convertir números hexadecimales es un buen elemento en nuestro trato diario con el registro.

Las notaciones decimales y binarias no se intercambian bien, de hecho nosotros hemos aprendido de pequeños la decimal sobre ‘todas las cosas’ ;-).

  1. El número 546 sería 5*10^2 + 4*10^1 + 6*10^0, es decir: 5*100+4*10+6*1. Esto es Base 10.

  2. El número 1011 sería 1*2^3 + 0*2^2 + 1*2^1 + 1*2^0, es decir: 1*8+0*4+1*2+1*1 o 11 en Base 10, aunque el número, dígitos 0 y 1, está en Base 2.

  3. Convertir Base 2 en Base 10 es trabajoso.

Esto nos lleva a la notación hexadecimal, o Base 16, con sólo dividir 16/2 convertir a binario (base 2) es algo sencillo. De todas formas, tener una tabla a mano para conversiones siempre viene bien.

Base 2 Binario

Base 16 Hexadecimal

Base 10 Decimal

0000 0 0
0001 1 1
0010 2 2
0011 3 3
0100 4 4
0101 5 5
0110 6 6
0111 7 7
1000 8 8
1001 9 9
1010 A 10
1011 B 11
1100 C 12
1101 D 13
1110 E 14
1111 F 15

Pasar el número 11111111 a hexadecimal es tan fácil como que 1111=F, así que 11111111 = FF.

Una última cosa a tener en cuenta, para diferenciar el número 12 decimal del número 12 hexadecimal se añade al segundo el prefijo 0x, quedando entonces el 0x12 como hexadecimal y el 12 como decimal.

Un pequeño truco para las conversiones es usar la calculadora de Windows, donde introduciendo un número lo convertimos a otras Bases con un par de clics.

 

Little-Endian, Big-Endian

En un número hexadecimal como 0x0102, el 0x01 es el byte más significativo y el 0x02 el menos significativo.

Los programas almacenan números en memoria de dos maneras: big-endian o little-endian. Si usan la primera, almacenan los bytes más significantes en memoria primero, seguido de los menos significantes, por ejemplo: 0x01020304 es 0x01 0x02 0x03 0x04. Sin embargo los procesadores Intel usan la otra manera, que significa que almacenan los menos significantes primero, seguido de los más significantes; el mismo número en memoria es =x04 0x03 0x02 0x01.

Aunque las herramientas que usaremos muestran todos los números –little o big-endian- correctamente, hemos de prestar atención cuando miramos números en valores binarios, ya que las herramientas no revierten el orden de los bytes por nosotros. Si vemos el número 0x2F 0xAA en valor binario recordemos que para revertir el orden de los bytes cogeremos el resultado 0xAA2F.

Algo así.

Codificación ANSI y Unicode

El esquema de codificación de caracteres prominente (texto que representan los equipos) era el ASCII, y que aún permanece hoy en día. En esta codificación, cada carácter es de 8 bits, o de un byte. Ya que ASCII era para idiomas occidentales, su uso fue limitado en países europeos y regiones cuyos idiomas contienen caracteres no incluidos en los 256 soportados por ASCII. Para superar esta limitación, la ISO creó una codificación estándar denominada Latin-1, que incluye caracteres europeos fuera del conjunto ASCII. Microsoft mejoró el Latin-1 y lo llamó ANSI. Pero ANSI sigue siendo de 8-bits y puede representar sólo 256 caracteres. Muchos idiomas tienen cientos de símbolos, en particular los asiáticos como el chino, koreano o japonés.

Para superar las limitaciones de las codificaciones de 8-bits, Microsoft junto a compañías como Apple e IBM, crearon el consorcio sin ánimo de lucro Unicode Inc. para definir una codificación nueva para juegos de caracteres internacionales. El trabajo realizado junto al ya en progreso por ISO, dio como resultado el estándar Unicode, que no es sino una codificación estándar de 16-bits, con lo que proporciona 65536 caracteres –más que suficiente para representar todos los idiomas del mundo.

Unicode es la codificación nativa de Windows, aunque es compatible con ANSI. Internamente, el sistema representa los archivos, objetos, rutas, como caracteres de 16-bits. También es normal almacenar datos en el registro usando Unicode.

Cadenas nulas o vacías

El concepto nulo es conocidísimo para los desarrolladores de C, 0x00, o sea el carácter NULL. Windows siempre acaba las cadenas con el carácter NULL, así los programas saben donde finaliza la cadena.

En el registro, el concepto es similar, el valor que contiene datos nulos significa que no contiene datos. Eso es, VACÍO. Normalmente cuando vemos un valor NULL en el registro leemos ‘valor no establecido’. Esto cambia si lo que se contiene es una cadena vacía, o sea cero caracteres de longitud o "". No es lo mismo NULL <> que "".