Interpretar las principales operaciones de registro con Process Monitor: RegCreateKey

En el primer artículo de esta seríe describí las funciones RegOpenKeyEx y RegCloseKey, así como la forma de interpretarlas, básicamente, desde la herramienta de Process Monitor. En esta nueva entrega me concentraré exclusivamente a la función RegCreateKeyEx, puesto que es un poco más completa de comprender cuando estamos haciendo diagnóstico.

RegCreateKeyEx

La operación principal de esta función, perteneciente a la API de Windows, consiste en crear una subclave de registro; en caso de que la subclave ya exista, la función la abre para utilizarla posteriormente. Ahora, tomando de ejemplo la subclave HKEY_CURRENT_USER\WinSide, la siguiente gráfica explica la definición que acabo de dar:

SNAGHTML256a06ea

 

HKEY_CURRENT_USER o su abreviación, HKCU, como lo dije en el primer artículo de esta serie, es una clave raíz; aunque WinSide es la verdadera subclave, se le puede llamar también subclave a todo el conjunto, es decir, HKEY_CURRENT_USER\WinSide.

Teniendo en cuenta la misma subclave de ejemplo, HKCU\WinSide, analicemos un poco el código que podríamos escribir en C/C++ con la API. Estas son las variables que requiere la función:

//RegCreateKeyEx
    HKEY hKey = HKEY_CURRENT_USER;
   LPCWSTR subKey = L”WinSide”;
    DWORD reserved = 0;
    LPWSTR classType = NULL;
    DWORD options = REG_OPTION_NON_VOLATILE;
    REGSAM samDesired = KEY_WRITE;
    LPSECURITY_ATTRIBUTES securityAttributes = NULL;
    HKEY createdKey;
    DWORD disposition;

La variable hKey contiene la clave raíz que pudo ser abierta por alguna función como RegOpenKeyEx o, como en este caso, una de las claves raíces que tiene el registro de Windows; la variable de subKey es un apuntador al nombre de la subclave que deseamos abrir o crear, en este caso WinSide; reserved es una variable reservada por el sistema y siempre debe ser cero; classType es el tipo de clase definida para la clave, pero puede ser NULL; la variable options me permite indicar diferentes comportamientos que puede tener la subclave, en el caso de REG_OPTION_NON_VOLATILE, le indica a Windows que la información almacenada se conserva después del reinicio; samDesired indica los derechos de acceso para la subclave, es decir, qué quiero hacer; la variable de securityAttributes almacena los atributos de seguridad, pero al darle NULL la subclave obtiene los predeterminados; createdKey va a tener el handle de la subclave abierta o creada; y disposition me indicará si la sublcave existía y se abrio o no existía y se creó.

Para poder ilustrar lo que Process Monitor captura, invocaré a la función RegCreateKeyEx para que abra o cree la subclave:

/* Función para crear o abrir la subclave
    HKEY_CURRENT_USER\WinSide */

    LONG createKey = RegCreateKeyEx(hKey, subKey, reserved,
                            classType, options, samDesired,
                securityAttributes, &createdKey, &disposition);

La variable createKey recibirá el código de error devuelto por el manejador de errores de Windows; yo puedo utilizar una función adicional para traducir eso a texto, pero obtaré por lo más sencillo que es validar si es satisfactorio o si es necesario mostrar el código de error, así:

if (createKey != ERROR_SUCCESS)
    {
        wprintf(L”Error opening the key. Code: %li\n”, createKey);
    }
    else
    {
        wprintf(L”Subkey was opened or created!\n”);
    }

 

Por supuesto, yo podría darle un poco más de estilo y aprovechar el valor retornado por disposition: es REG_CREATED_NEW_KEY si Windows creó la clave desde cero o REG_OPENED_EXISTING_KEY si la clave ya existía y solo se abrió. Nada más útil que llamar al condicional switch.

switch (disposition)
        {
        case REG_CREATED_NEW_KEY:
            wprintf(L”Key did not existed and was created\n”);
            break;

        case REG_OPENED_EXISTING_KEY:
            wprintf(L”Key existed and was just opened\n”);
            break;

        default:
            wprintf(L”Unkown value\n”);
            break;
        }

El código de toda la validación se vería así:

if (createKey != ERROR_SUCCESS)
    {
        wprintf(L”Error opening the key. Code: %li\n”, createKey);
    }
else
    {
       
        switch (disposition)
        {
          case REG_CREATED_NEW_KEY: //Key was created
            wprintf(L”Key did not existed and was created\n”);
            break;

          case REG_OPENED_EXISTING_KEY: //Key was opened
            wprintf(L”Key existed and was just opened\n”);
            break;

          default:
            wprintf(L”Unkown value\n”);
            break;
        }

        //Do not forget to close the handle!
        RegCloseKey(createdKey);
    }

De esta forma la consola mostrará el mensaje adecuado según se haya creado o abierto la subclave.

Aquí pueden ver la documentación oficial de RegCreateKeyEx:
https://msdn.microsoft.com/en-us/library/windows/desktop/ms724844(v=vs.85).aspx 

Process Monitor en acción

Empecemos por ver cómo nos muestra Process Monitor las operaciones que se hagan sobre la subclave HKCU\WinSide, para eso basta con filtrar por ruta y proceso de la aplicación, así:

image

Al ejecutar la aplicación, sin que esté la subclave creada, la validación se va por el REG_CREATED_NEW_KEY y me muestra el mensaje correspondiente:

image

¿Qué pasa en Process Monitor? Esto es lo que me muestra después de mostrado el mensaje:

image

La primera operación que hay listada es RegCreateKey, que corresponde a la que en código tengo como RegCreateKeyEx, está trabajando sobre el Path de HKCU\WinSide, handle que abrió o creó, según sea la disposición. El resultado, como también pueden ver fue SUCCESS, lo que indica que la operación se completó sin problemas y, finalmente, la columna de Detail me da datos importantes como el Desired Access (derechos de acceso solicitados) y Disposition (que me indica si la clave se creó o se abrió).

Después de estas operaciones, vemos que RegCloseKey se encarga de hacer la operación sobre la misma subclave, HKCU\WinSide, para cerrar el handle, es decir, terminar lo que se está haciendo sobre la subclave.

Noten que aunque yo conozco el código, los datos extraídos son todos desde Process Monitor, así que no necesitaría el código para saber qué pretende hacer la aplicación efectuando esa operación. Como datos adicionales, puedo entrar a las propiedades de la operación haciendo doble clic, pestaña de Process y ver detalles más completos:

image


Integrity
me indica el nivel de integridad en el que se está ejecutando el proceso, que en este caso es Medium, como cada proceso de usuario estándar; Architecture me indica, como su nombre en inglés lo dice, la arquitectura de la aplicación, que en este caso es 32-bit, por lo que en algún punto está actuando también la capa de emulación de WOW64.

Si vamos a la pestaña de Stack, podremos ver detalles de toda la transición entre User Mode y Kernel Mode, información bastante completa para alguien que entienda de Windows Internals. Una de las cosas que se puede identificar, por ejemplo, es que puedo ver que a la función exacta que se llama es RegCreateKeyExW (el W al final indica que se compiló como Unicode).

image


Nota:
para ver claramente esto, es necesario que Process Monitor tenga configurado los símbolos.

Aunque desde la vista general de Process Monitor puedo ver los detalles, también está disponible la pestaña de Event en donde tengo todo el resumen:

image

Es importante anotar que así en el código de la aplicación el valor de disposition sea NULL, Process Monitor podrá mostrarlo y así sabremos, a ciencia cierta, si la clave se abrió o se creó. Por ejempo, si yo ejecuto otra vez la misma aplicación de muestra, pero esta vez sin indicarle el disposition, puedo el resultado será el mismo:

image

Debido a que la subclave ya existía, puedo concluir, gracias al detalle de Process Monitor (Disposition: REG_OPENED_EXISTING_KEY), que Windows abrió la clave sin necesidad de crearla otra vez.

Una característica particular que tiene las llamadas a la API es que puedo crear más de una subclave de una vez. Por ejemplo, si en el código que mostré en este artículo quisiera abrir o crear la subclave HKCU\WinSide\Learning\Internals, bastaría con indicarle a la variable subKey todo el árbol, así:

LPCWSTR subKey = L”WinSide\\Learning\\Internals”;


Nota:
el doble signo de ‘\’ es para indicarle que deseamos poner una barra inversa y no una secuencia de escape.

Después de esto, solo es necesario ejecutarlo y esperar el resultado. El mensaje que nos devolverá será para toda la subclave y no para cada una individualmente.

En Process Monitor, sin embargo, podremos ver todo el proceso:

image

Lo primero que intenta hacer la aplicación es abrir la subclave HKCU\WinSide\Learning\Internals; como la clave no existe, empieza a hacer todo el procedimiento de abrir o crear desde la primera subclave, WinSide, hasta la última subclave, Internals. Noten que cada subclave se va cerrando después de pasar el handle a la otra. Cuando termina toda la operación hasta Internals, todos los handles se cierran y el resultado es nuestra subclave creada:

image

Desde Process Monitor, entonces, podemos identificar cuál es la subclave final desde antes de que la aplicación la cree y hacer un seguimiento detallado de cada subclave.

Espero que esto les pueda servir tanto como a mi me está sirviendo para aprender. Intentaré mejorar cada vez más las entradas, conforme vaya aprendiendo yo; además, es posible que toque otras funciones, sea de registro o de sistema de archivos.

 

P.D.: cualquier comentario o corrección es bienvenido.

 

Saludos,

—Checho

Personalizar la barra de tareas de Windows 10 con directivas de grupo

El pasado mes de mayo escribí un artículo sobre una característica bastante llamativa en Windows 10, versión 1511, que, expandiendo lo que ya se podía en Windows 8.1 Update, permitía crear un diseño parcial del menú de inicio para todos los usuarios, utilizando Directivas de grupo.

Windows 10, versión 1607, agregó otra funcionalidad más a estas características para anclar una serie de accesos predeterminados en la barra a través de Directivas de grupo y así ayudar a los administradores de infraestructura a estandarizar fácilmente las personalizaciones de usuario. En este artículo explicaré cómo podemos realizar estas personalizaciones.

Requerimientos

1. Controladores de dominio con los ADMX actualizados a Windows 10, versión 1607

2. Equipo con Windows 10, versión 1607, que sirva de referencia

3. Equipos con Windows 10 Enterprise o Education, versión 1607, en donde se implemente la directiva de grupo

Nota: esta característica no está disponible en ediciones Home y Pro.

Paso 1: configurar la barra de tareas

Estos pasos se deben realizar en el equipo de referencia, que puede estar o no unido al dominio de la empresa. Lo más importante es que si vamos a referenciar aplicaciones no integradas en Windows, estas deben instalarse también en los equipos en donde se va a desplegar la directiva.

Lo primero que hay que hacer, después de instalar las aplicaciones, si es que se requiere agregar un acceso directo, es anclar todos los accesos directos que vamos a predeterminar en los demás equipos. Basta con buscar la aplicación en el menú de inicio, hacer clic derecho y luego clic izquierdo en Anclar a la barra de tareas.

image

Para este artículo, yo anclé el Internet Explorer, Notepad++, Conexión a acceso remoto y el Símbolo del sistema.

image

Paso 2: crear y guardar el XML

El siguiente paso es crear o personalizar el XML. Microsoft provee una muestra en su documentación, así solo debemos dedicarnos a encontrar el Desktop Application Link Path adecuado para cada aplicación anclada; se utilizan dos rutas:

  • %APPDATA%\Microsoft\Windows\Start Menu\Programs
  • %ALLUSERSPROFILE%\Microsoft\Windows\Start Menu\Programs

Nota: las aplicaciones de interfaz moderna también se pueden anclar y relacionar en el XML que se crea, pero no las mostraré en el ejemplo, puesto que casi no se ve en la vida real; de hecho, las empresas tienden a bloquear estas aplicaciones.

Los accesos directos pueden estar en una u otra, por lo que toca buscarlo manualmente carpeta por carpeta. Por ejemplo, el acceso al Notepad++ está en:

%ALLUSERSPROFILE%\Microsoft\Windows\Start Menu\Programs\Notepad++\Notepad++.lnk

image

El Internet Explorer, por poner otro ejemplo, está en la ruta:

%APPDATA%\Microsoft\Windows\Start Menu\Programs\Accessories\Internet Explorer.lnk

image

Ambas rutan deben estar dentro de la etiqueta <taskbar:DesktopApp DesktopApplicationLinkPath=/> del XML, así:


<?xml version=”1.0″ encoding=”utf-8″?>
<LayoutModificationTemplate
    xmlns=”
http://schemas.microsoft.com/Start/2014/LayoutModification”
    xmlns:defaultlayout=”http://schemas.microsoft.com/Start/2014/FullDefaultLayout”
    xmlns:start=”http://schemas.microsoft.com/Start/2014/StartLayout”
    xmlns:taskbar=”http://schemas.microsoft.com/Start/2014/TaskbarLayout”
    Version=”1″>
  <CustomTaskbarLayoutCollection>
    <defaultlayout:TaskbarLayout>
      <taskbar:TaskbarPinList>
        <taskbar:DesktopApp DesktopApplicationLinkPath=”%APPDATA%\Microsoft\Windows\Start Menu\Programs\Accessories\Internet Explorer.lnk”/>
        <taskbar:DesktopApp DesktopApplicationLinkPath=”%ALLUSERSPROFILE%\Microsoft\Windows\Start Menu\Programs\Notepad++\Notepad++.lnk”/>
        <taskbar:DesktopApp DesktopApplicationLinkPath=”%ALLUSERSPROFILE%\Microsoft\Windows\Start Menu\Programs\Accessories\Remote Desktop Connection.lnk”/>
        <taskbar:DesktopApp DesktopApplicationLinkPath=”%APPDATA%\Microsoft\Windows\Start Menu\Programs\System Tools\Command Prompt.lnk”/>
       
      </taskbar:TaskbarPinList>
    </defaultlayout:TaskbarLayout>
</CustomTaskbarLayoutCollection>
</LayoutModificationTemplate>


image

Nota: la base de este XML está tomada de la documentación de Microsoft.

Después de agregar las entradas correspondientes a cada acceso directo anclado, debemos guardar el XML con cualquier nombre descriptivo y ubicaro en una ruta de red, en la que pueda acceder el controlador de dominio que creará la directiva. Para este caso, yo la ubiqué en \\DC\Resources y lo llamé TaskBarLayout1.xml.

image

Paso 3: crear y desplegar la directiva

En el controlador de dominio, después de actualizar los ADMX, creamos o editamos la GPO destinada para personalizar la barra de tareas en los equipos con Windows 10, versión 1607, y realizamos lo siguiente:

1. User Configuration > Policies > Administrative Templates > Start Menu and Taskbar

2. Doble clic en la plantilla de Start Layout

image

3. Habilitamos la directiva y escribimos debajo de Start Layout File la ruta del XML

image

4. Clic en Apply y OK para terminar

Paso 4: probar la directiva de grupo

Si todo sale bien, cuando unamos un nuevo equipo al dominio o simplemente  reiniciemos para forzar directivas de grupo, la barra de tareas debe aparecer con todos los nuevos accesos a la derecha.

Así está la barra de tareas sin aplicar la directiva:

image

Así se ve después de aplicada:

image

Parece increíble que una característica así se haya tardado tanto en llegar, ¿no creen?

Espero sea de utilidad.

Saludos,

—Checho

Explorando el «Registry Redirector» en Windows

Antes de empezar

Si no estoy mal, este es el primer artículo en el que escribiré sobre una característica interna del sistema operativo; así que pido disculpas de antemano por cualquier equivocación que tenga y por si el código que aquí expondré no es el más profesional. Dicho esto, ¡empecemos!

Windows de 32 bit en Windows de 64 bit (WOW64)

Debido a que el trabajo de «Registry Redirector» hace parte de WOW64 , es necesario dar una introducción, mas no voy a profundizar porque de esto no se trata el artículo y, a decir verdad, no tengo aún el conocimiento para exponerlo.

«Windows 32 –bit On Windows 64-bit (WOW64)» es una capa de emulación que permite ejecutar aplicaciones basadas en 32 bits en un sistema operativo de 64 bits sin que la aplicación lo llegue a percibir. WOW64 tiene una colección de DLLs en modo usuario (existe modo usuario y modo kernel) que interceptan llamadas desde y hacia un proceso de 32 bits y hace la respectiva traducción para que todo funcione en el ambiente de 64 bits.

Registry Redirector

Lo primero que hay que decir es que este es que el mecanismo que voy a pasar a describir no es nuevo, pues existe desde Windows Vista, pero aún tiene influencia en problemas relacionados a la compatibilidad de aplicaciones.

El trabajo del «Registry Redirector» es aislar las aplicaciones de 32 y de 64 bits de ciertas partes del registro con diferentes nodos  para almacenar la información. Básicamente, intercepta la llamada que hace la aplicación, sea de 32 o de 64 bits, a su respectiva ubicación lógica y la dirige a una ubicación física. Este proceso es completamente transparente para la aplicación (y para nosotros), así que las aplicaciones de 32 bits, por ejemplo, pueden seguir accediendo a sus datos como si estuvieran en un sistema base de 32 bits. Esto es para que puedan correr y convivir sin problemas.

Las subclaves que son dirigidas se guardan en la subclave de Wow6432Node; por ejemplo, todo lo que una aplicación de 32 bits intente escribir en HKEY_LOCAL_MACHINE\Software es dirigido a la subclave HKEY_LOCAL_MACHINE\Wow6432Node.

Nota: de aquí en adelante utilizaré las siglas de HKLM y HKCU para poder referirme a las claves de HKEY_LOCAL_MACHINE y HKEY_CURRENT_USER, respectivamente.

¿Cómo lo vemos en acción?

Para poder ver y entender este mecanismo, decidí escribir, con mi pobre conocimiento en C, una aplicación propuesta por la documentación oficial de Microsoft y mostrarla en este artículo, con la ayuda adicional de Process Monitor.

La aplicación

La aplicación que escribí se llama DemoApp.exe y lo que hace es tratar de abrir la subclave WinSide, ubicada en la subclave HKEY_LOCAL_MACHINE\Software. Si la subclave existe, consulta el contenido del valor predeterminado, Default, y lo muestra en consola; si no, la aplicación crea la subclave de WinSide , escribe el contenido del valor predeterminado y procede a mostrarlo en consola. 

Nota: en cada subclave que se crea siempre existe el valor de Default, que puede o no tener un contenido.

A continuación, muestro una imagen en donde trato de ilustrar las operaciones que hace la aplicación.

SNAGHTML1cd7165

La imagen anterior, aunque resume el comportamiento general de la aplicación, es fiel a la gráfica cuando el ejectuable es de la misma arquitectura que el sistema operativo instalado; sin embargo, cuando la aplicación es de 32 bit y se ejecuta en un sistema de 64, el Registry Redirector actuará sobre la subclave de HKLM\WinSide y la ubicación física cambiará, así:

SNAGHTML36a031

Esta dirección al nodo físico, como ya lo dije, es completamente transparente para la aplicación, así que el desarrollador no tiene que preocuparse realmente por este mecanismo.

El código (para los interesados)

Importante: insisto en que soy un programador novato de C, así que seguramente encontrarán errores o mejoras prácticas en mi código. ¡Cualquier aporte es bienvenido!

Lo primero que hice fue crear una serie de macros para remplazar el mensaje según esté compilada la aplicación; es decir, si ejecuto la versión compilada a 64 bits, el mensaje será «64-bit app on WINx64», de lo contrario, «32-bit app on WINx64».

#ifdef _M_AMD64

#define MSG L”64-bit app on WINx64.\n”

#else

#define MSG L”32-bit app on WINx64.\n”

#endif

Luego creé una función llamada showValue que utiliza la función RegGetValue de la API de Windows para consultar el contenido del valor Default y luego mostrarlo. La función personalizada quedó así:

/*This function receives some variables to show a registry value’s –
content, but only REG_SZ is working by now.*/
void showValue(HKEY openKeyResult, LPCWSTR regValueName, DWORD flags)
{
    //Buffer that receives the value’s data.
    WCHAR valuesData[255];
    PVOID pValuesData = valuesData; //A.K.A. pvData
    DWORD sizeOfBuffer = sizeof(valuesData); //A.K.A. pcbData
    DWORD typeOfData;

    LONG getValue = RegGetValue(openKeyResult, NULL, regValueName,
                                flags, &typeOfData, pValuesData,  &sizeOfBuffer);

    if (getValue != ERROR_SUCCESS)
    {
        wprintf(L”Error getting the value. Code: %li\n”, getValue);
    }
    else
    {
        switch (typeOfData)
        {
        case REG_SZ:
            wprintf(L”Value’s data: %s\n”, (PWCHAR)pValuesData);
            break;

        default:
            wprintf(L”No other types are allowed.\n”);
            break;
        }
    }

}

Nota: RegGetValue está documentada en la página oficial de MSDN:
https://msdn.microsoft.com/en-us/library/windows/desktop/ms724868(v=vs.85).aspx

La función recibe una variable openKeyResult, que es el handle a la subclave abiera previamente con RegOpenkeyEx (en wmain la utilizo); regValueName, que es el nombre del valor a consultar y flags, que me indica el tipo de datos que voy a utilizar.

Finalmente está el código de la función principal wmain. Aquí lo que hice fue declarar las variables necesarias para usar la función RegCreateKeyEx que abre o crea la subclave, luego las que requiere RegSetValueEx para escribir el contenido del valor Default y las de RegGetValue para consultar e imprimir el contenido del valor Default.

La siguiente porción de código se puede resumir así en esta secuencia:

¿Existe la subclave HKEY_LOCAL_MACHINE\Software\WinSide?

  • : consultar e imprimir el contenido del valor Default.
  • No: crear la subclave WinSide, escribir el contenido del valor Default e imprimirlo.

Así se ve todo esto usando C y la API de Windows:

int wmain()
{

    void showValue(HKEY openKeyResult, LPCWSTR regValueName, DWORD flags);
   

    //RegCreateKeyEx
    HKEY hKey = HKEY_LOCAL_MACHINE;
    LPCWSTR subKey = L”Software\\WinSide”;
    DWORD reserved = 0;
    LPWSTR classTypeOfKey = NULL;
    DWORD options = REG_OPTION_NON_VOLATILE;
    REGSAM samDesired = KEY_READ | KEY_WRITE;
    LPSECURITY_ATTRIBUTES securityAttributes = NULL;
    //Handle to the opened or created key.
    HKEY openKeyResult;
    DWORD disposition;

    //RegSetValueEx
    LPCWSTR valueName = NULL; //To set the default value’s content.
    DWORD typeOfData = REG_SZ;
    const BYTE *pData = (const BYTE*)MSG;
    DWORD size = sizeof(MSG);

    //RegGetValue
    LPCWSTR valueNameDefault = NULL; //To get the default value’s data.

    //Restrict the data type of value queried.
    DWORD flags = RRF_RT_ANY;
       

    LONG createKey = RegCreateKeyEx(hKey, subKey, reserved, classTypeOfKey,
                                    options, samDesired, securityAttributes,
                                    &openKeyResult, &disposition);

    if (createKey != ERROR_SUCCESS)
    {
        wprintf(L”Error opening or creating the key. Code: %li\n”, createKey);

    }
    else
    {
        LONG setValue;
       
        switch (disposition)
        {
        case REG_CREATED_NEW_KEY:

            //Let’s create the value!
            setValue = RegSetValueEx(openKeyResult, valueName, reserved,
                typeOfData, pData, size);

            if (setValue != ERROR_SUCCESS)
            {
                wprintf(L”Registry value could not be set.\n”);
            }
            else
            {
                wprintf(L”Registry value set.\n”);
            }

            //Let’s query it!
            showValue(openKeyResult, valueNameDefault, flags);
            break;

        case REG_OPENED_EXISTING_KEY:

            //Let’s query the value!
            showValue(openKeyResult, valueNameDefault, flags);
            break;

        }

        //Closing the key.
        RegCloseKey(openKeyResult);

       
    }

    return 0;

}

Lo más interesante de todo esto es que en las variables hKey y subKey estoy apuntando HKLM como clave y Software\WinSide como subclave, así que en teoría siempre debería escribir ahí; sin embargo, el Registry Redirector se encargará de dirigir la escritura a la ubicación física de acuerdo a la arquitectura del proceso, es decir, HKLM\Software\WinSide para x64 y WKLM\Software\Wow6432Node\WinSide para x86.

El resultado

Afortunadamente, Visual Studio me permite cambiar la arquitectura en la que la aplicación compila sin mucho esfuerzo, así que puedo mostrar el resultado fácilmente.

image

Ejecución de la aplicación a 32 bits en Windows de 64 bits

Cuando lanzo DemoApp.exe compilada a 32 bits, recibo este mensaje:

image

Como lo mencioné en la gráfica de la aplicación y en el código, estoy consultando el contenido del valor Default y mostrándolo. Si analizamos la traza con Process Monitor, veremos lo que ocurrió:

SNAGHTMLb91b44

Primero se muestra la operación de RegCreateKey, la cual intenta abrir la clave y si no existe, la crea; luego RegSetValue para crear el contenido del valor Default y finalmente RegQueryValue, operación que remplaza al RegGetValue en el código que expuse anteriormente para obtener el contenido del valor Default y poder imprimirlo después. Noten que todas las operaciones se hacen sobre la ruta HKLM\Software\WOW6432Node\WinSide, puesto que el proceso es de 32 bits.

Al ingresar a las propiedades de la entrada RegCreateKey, pestaña de Stack, puedo ver todas las ocurrencias de las DLLs, encargadas de interceptar las llamadas y realizar la traducción:

image

La aplicación cree que escribe en la ubicación física nativa, pero en cada operación que haga siempre será dirigida a WOW6432Node\WinSide.

Nota: existe una excepción en donde una aplicación puede leer y escribir en la subclave nativa, así el mecanismo del Registry Redirector esté funcionando; solo es necesario ingresar en la máscara de acceso, samDesired, el derecho de acceso KEY_WOW64_64KEY para usarla luego con RegCreateKeyEx, así:

REGSAM samDesired = KEY_READ | KEY_WRITE | KEY_WOW64_64KEY;

Si al ejecutar la aplicación los descriptores de seguridad (los que me dicen si puedo) no me lo deniega, la aplicación escribirá en HKLM\Software, sin hacer dirección a Wow6432Node.

Nota: no tengo idea de cómo se puede establecer esto en desarrollos con .Net, pero me imagino que existe la forma.

Ejecución de la aplicación a 64 bits en Windows de 64 bits

Esto es lo que pasa cuando lanzo la aplicación, compilada a 64 bits, en Windows de la misma arquitectura:

image

Observen que el mensaje ahora es «64-bit app on WINx64», pero es la misma aplicación.

Así se ve en Process Monitor:

image

Al estar la aplicación a 64 bits, no es necesario que actúe la capa de emulación de WOW64, por ende, el mecanismo del Registry Redirector tampoco se activa y la aplicación escribe en la ubicación nativa: HKLM\Software\WinSide.

Lo mismo a nivel de Stack, la comunicación es directa:

image

Eso es todo lo que tengo para escribir sobre el Registry Redirector. Agradezco mucho cualquier corrección, pues me ayudarán a aprender.

Espero escribir próximamente sobre Registry Reflection para ampliar un poco más WOW64.

Saludos,

—Checho