La aplicación que daba Acceso Denegado con el proceso elevado, UAC, Process Explorer, ResHacker y su solución

Una de las cosas que hacemos en Tulpep, empresa donde actualmente trabajo, cuando solucionamos un problema de alguna aplicación que requiere muchos pasos manuales, es ofrecer una solución alternativa en la que creamos un instalador y automatizamos los procesos con el objetivo de que sea más fácil para el cliente. Estos procesos suelen hacerse con Inno Setup, a no ser que sea un desarrollo propio.

Hace unos días terminé un instalador que debía entregar a un cliente y por supuesto, debía probar el funcionamiento en un laboratorio. Una de las Fuentes que tenía referenciado en el script de Inno Setup, era un .BAT que iba a correr después de terminada la instalación:

2015-04-18_19-20-58

El archivo en cuestión, utilizaba Robocopy para copiar unos archivos necesarios de la carpeta fuente de instalación, a la de otro programa que se enviaba a instalar desde el asistente:

2015-04-18_19-32-02

Hasta aquí nada raro, de hecho la instalación funcionaba muy bien desde el Inno Setup que previamente había lanzado como administrador.

El problema

Una vez probado todo, procedí a compilar el instalador y a probar desde él toda la instalación. Sabía que debía tener privilegios administrativos para las tareas que iba a ejecutar, pero solo con darle doble clic al Setup.exe que había creado, Windows me pedía elevación de privilegios:

2015-04-18_19-39-05

Con eso creí que era suficiente, ya que si el instalador pedía elevación, todo lo que ejecutara debía obtener el mismo token administrativo y proceder a realizar operaciones.

Sin embargo, al llegar al momento en que se lanzaba el BAT, recibí un mensaje de acceso denegado:

2015-04-18_19-52-32

Ahí se quedaba en un bucle infinito tratando de escribir y no pasaba. ¿Por qué?

La causa

Normalmente un proceso siempre adquiere el token o privilegios otorgados por su proceso padre; además de sus niveles de integridad. Si este ejecutable me pedía elevación, yo suponía que debía estar con los privilegios elevados pero, la única forma de comprobarlo iba a ser con Process Explorer de Sysinternals.

Lo que hice fue ejecutar Proccess Explorer, habilitar la columna de Integirty Levels y dejarlo en segundo plano mientras lanzaba la aplicación haciendo doble clic y aceptando el mensaje del UAC. Esto fue lo que encontré al dejar el instalador abierto y ver en Procexp:

2015-04-18_20-12-48

El árbol que muestra Process Explorer, ubica el proceso padre mucho más alineado a la izquierda que el hijo. En este caso, el proceso padre era Setup.exe, luego Setup.tmp y abajo de él, pero en el mismo nivel, estaban otros Setup y finalmente el cmd.exe que a su vez llamaba al Robocopy.exe.

A parte de que se creaban dos instancias: Setup.exe y Setup.tmp; el nivel de integridad que tenía heredado cmd y Robocopy era Medium (ver gráfica), cuando en realidad debería ser High como el que estaba arriba de cmd.exe. Todo esto quiere decir que cmd.exe estaba heredando el token del primer Setup.exe, así que siempre iba a ejecutarse con privilegios estándar y NO elevados.

La ventana del UAC que me pedía consentimiento elevaba la segunda instancia del Setup.exe, pero esto no servía de nada, ya que siempre los demás ejecutables o archivos por lotes que llamaba iban a seguir ejecutándose sin permisos administrativos. El resultado de todo esto: ¡Acceso Denegado!

Ahora, ¿Qué pasaba al tomarme el trabajo de darle clic derecho sobre el Setup.exe y seleccionar Ejecutar como administrador? Esto muestra Process Explorer:

2015-04-18_21-10-33

Básicamente, no había otra instancia del .EXE y .TMP. Las únicas dos instancias que existían estaban con el nivel de integridad en High (Alto); o sea que todo lo que el proceso llamara se iba a ejecutar con privilegios administrativos. Por ejemplo, el Robocopy:

2015-04-18_21-14-20

En pocas palabras, para que todo se ejecutara e instalara correctamente, necesitaba que la aplicación obtuviera el token administrativo desde su proceso padre.

¿Por qué una instancia quedaba elevada al hacer doble clic? No sé responder eso, pero lo que sí sabía en ese momento es que el instalador no estaba pidiendo elevación de privilegios administrativos. ¿Por qué me salía el primer mensaje pidiendo elevación? No sé, probablemente el UAC estaba

En este punto, una de las personas que más admiro, Ricardo Polo, me dio la pista clave: El archivo manifiesto de UAC que estaba en el instalador. No entraré en detalle porque me falta mucho conocimiento para escribir bastante al respecto, pero básicamente es un XML donde entre otras cosas, se le pide a Windows con qué nivel de privilegios debe ser ejecutada la aplicación. Existen tres, los máximos privilegios que el usuario le pueda otorgar, como se invoque (que se traduce básicamente a estándar) y pedir administrador. Técnicamente, se reconocen como: highestAvailable, asInvoker y requiereAdministrator.

Intentaré describir en otro post cómo lo hice, pero en esencia utilicé Strings de Sysinternals para ver los binarios del instalador y de ese resultado buscar el manifiesto. Este fue el resultado al verlo en un TXT:

2015-04-18_21-35-09

Debido a que el manifiesto que Inno Setup integraba a la aplicación pedía asInvoker, siempre se iba a ejecutar con privilegios estándar si se lanzaba con doble clic. El reto consistía en modificar ese manifiesto para que pidiera privilegios administrativos al ejecutarse.

La solución

Para poder modificar el manifiesto sobre el ejecutable, descargué Resource Hacker y procedí a hacer lo siguiente:

1. Lancé Resource Hacker haciendo clic derecho y Ejecutar como administrador.

2. Abrí el instalador desde ResHacker haciendo clic en File > Open.

2015-04-18_21-42-59

3. Expandí el nodo 24 > 1 y clic en 1033 para ver el string que tenía. Estos números pueden variar:

2015-04-18_21-44-53

4. Cambié el level por requiereAdministrator y clic en el botón Compile Script.

2015-04-18_21-52-38

5. Hice clic en el menú File > Save as…

2015-04-18_21-56-53

6. Le puse un nombre descriptivo con la extensión .EXE y lo guardé:

2015-04-18_21-58-34

7. Cerré Resource Hacker.

Finalmente, fui hasta la ruta del instalador y el nuevo instalador ahora tenía el escudo de UAC que identifica el requerimiento de privilegios para ejecutarse:

2015-04-18_22-00-08

Al ejecutarlo, aparecía el UAC y después de aceptar se elevaba el privilegio como debía ser:

2015-04-18_22-01-04

Este mismo procedimiento se le puede aplicar a cualquier instalador que deseen modificarle el manifiesto, si es que lo tiene.

Espero sea de utilidad.

PD: No olviden seguirme en Twitter: www.twitter.com/secalderonr

Checho

2 comentarios en “La aplicación que daba Acceso Denegado con el proceso elevado, UAC, Process Explorer, ResHacker y su solución”

  1. Hola, Checho. ¿Cómo es la línea de la sección [Run] del script de Inno Setup que llama al archivo .bat? Quizá no tengas que dar tantas vueltas si usas los modificadores apropiados: http://www.jrsoftware.org/ishelp/index.php?topic=runsection

    Puedes observar qué acciones y decisiones toma un programa de instalación basado en Inno Setup usando el parámetro /log. Concretamente te indicaría si las entradas [Run] se han ejecutado con el token de usuario original (original user) o el elevado (current user). El archivo se guarda en %TEMP% a menos que especifiques una ubicación exacta como en /log=»c:docssetup.log».

    Incluso al final podría ser más conveniente reescribir las sentencias del archivo BAT en código Pascal de Inno Setup usando la función Exec para ejecutar programas.

  2. @Ramón, lamento haber respondido tan tarde (la costumbre de no tener comentarios en el blog). La línea que tenía estaba así:

    Filename: «{app}{#CopyFiles}»; Description: «Copiar todos los archivos necesarios (Obligatorio).»; Flags: postinstall skipifsilent

    PD. ¿A qué hora aprendiste tantas cosas? =P

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *