2012-02-06 10 views
8

estoy preparando un módulo de Delphi, que establece un enlace en un hilo para grabar una macro:SetWindowsHookEx para WH_JOURNALRECORD falla en Vista/Windows 7

FHandleRec := SetWindowsHookEx(WH_JOURNALRECORD, FRecordProc, HInstance, 0); 
FHandlePlay := SetWindowsHookEx(WH_JOURNALPLAYBACK, FPlayProc, HInstance, 0); 

Eso funciona bien en WinXP, pero en Vista/Windows 7 falla con ERROR_ACCESS_DENIED. He encontrado en Google (this) refiriéndose (that). La cita:

Un proceso de privilegios más bajo no puede: ... Usar ganchos de diario para supervisar un proceso de privilegios superior .

juzgado sin éxito: aplicación

  1. Ejecutar como administrador. Probablemente el hilo se inició con privilegios inferiores que el hilo principal (aunque no soy 100% seguro)
  2. Suplantar el hilo con el contexto de seguridad del administrador tampoco ayuda.

El ejemplo de código:

if LogonUser(PWideChar(sAdminUser), PWideChar(sDomain), PWideChar(sPwd), 
      LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, hToken) then 
begin 
    if not ImpersonateLoggedOnUser(hToken) then 
    raise Exception.Create('Error impersonating the user'); 
end; 
FHandleRec := SetWindowsHookEx(WH_JOURNALRECORD, FRecordProc, HInstance, 0); 

LogonUser y ImpersonateLoggedOnUser ejecutar sin errores.

Otras posibilidades para probar:

  1. activarlo de forma permanente. Esto ayuda, pero no puedo obligar a los usuarios del módulo a hacer eso.
  2. Un cliente de módulo firma una aplicación y la pone en una ubicación de confianza . No lo intenté, pero eso complica radicalmente el uso del módulo para los usuarios.
  3. Coloque el módulo en alguna aplicación firmada y distribuya EXE. Eso romperá algunas funciones básicas.

¿Podría mostrar el código que está configurando el gancho en Visa/Windows 7 o sugerir la solución de trabajo?

+2

Deberá incrustar un manifiesto para pedir permiso de elevación al usuario. Sospecho que cae en la categoría "se complica radicalmente". –

Respuesta

8

Lea con más cuidado la sección "Aislamiento de privilegios de la interfaz de usuario" de that article. Se refiere a niveles de integridad, no a permisos de usuario. Es por eso que suplantar a otro usuario no resuelve el problema. El nivel de integridad se establece cuando el proceso se inicia por primera vez y no se puede cambiar dinámicamente en el código.

usuario Aislamiento de privilegios en interfaz (UIPI) es uno de los mecanismos que ayuda a los procesos en ejecución como administrador total de procesos que se ejecutan como una cuenta más baja que un administrador en el mismo escritorio interactivo aislar. UIPI es específico para el subsistema de gráficos ventana y , conocido como USER, que admite Windows y los controles de interfaz de usuario .UIPI impide una aplicación de privilegios más baja desde utilizando los mensajes de Windows para enviar la entrada de un proceso a un proceso de privilegios superior. El envío de entradas de un proceso a otro permite que un proceso inyecte una entrada en otro proceso sin que el usuario proporcione acciones de teclado o mouse.

Windows Vista implementa UIPI definiendo un conjunto de niveles de privilegios de interfaz de usuario de forma jerárquica. La naturaleza de los niveles es tal que los niveles de privilegios más altos pueden enviar mensajes de ventana a las aplicaciones que se ejecutan en niveles inferiores. Sin embargo, los niveles inferiores no pueden enviar mensajes de ventana a las ventanas de aplicaciones que se ejecutan en niveles superiores .

El nivel de privilegio de la interfaz de usuario está en el nivel de proceso. Cuando se inicializa un proceso , el subsistema de usuario llama al subsistema de seguridad para determinar el nivel de integridad de escritorio asignado en el token de acceso de seguridad del proceso . El nivel de integridad del escritorio se establece en el subsistema de seguridad cuando se crea el proceso y no cambia . Por lo tanto, el nivel de privilegio de la interfaz de usuario también se establece en el subsistema del usuario cuando se crea el proceso y no cambia.

Todas las aplicaciones ejecutadas por un usuario estándar tienen la misma interfaz de usuario nivel de privilegio. UIPI no interfiere ni cambia el comportamiento del mensaje de ventana entre aplicaciones en el mismo nivel de privilegio. UIPI entra en vigor para un usuario que es miembro del grupo de administradores y puede ejecutar aplicaciones como usuario estándar (a veces denominado proceso con token de acceso filtrado) y también procesos que se ejecutan con un administrador completo token de acceso en el mismo escritorio. UIPI previene procesos de privilegios más bajos desde accediendo a procesos de privilegios más altos mediante el bloqueo del comportamiento enumerado a continuación.

  • Utilice los ganchos de diario para supervisar un proceso de privilegios mayor.

Según this article, su aplicación necesita un manifiesto UAC que especifica tanto requestedExecutionLevel=requireAdministrator y uiAccess=True. El derecho uiAccess es importante:

Al especificar uiAccess =”true” en los requestedPrivileges atribuyen, la aplicación está indicando un requisito para eludir las restricciones UIPI ... Un proceso que se puso en marcha con derechos UIAccess:

  • Puede establecer ganchos de diario.
+0

Remy, muchas gracias por la respuesta. Supongamos que tengo el servidor COM fuera de proceso - exe firmado y manifestado con uiAccess = True. El servidor establece los procedimientos de enlace e intercambia los datos con la aplicación del usuario a través de las devoluciones de llamada COM. Entonces, todo el procesamiento aún lo realiza la aplicación del usuario.Pregunta: cuando una aplicación de interfaz de usuario estándar (no firmada y en ejecución sin elevación de derechos) utiliza un servidor COM de este tipo, ¿podrá el servidor seguir configurando los ganchos de diario? – AlexeyDaryin

+0

@AlexeyDaryin: como su nombre lo indica, un servidor COM fuera de proceso se ejecuta en su propio proceso. Los derechos del proceso de la aplicación estándar no afectarán los derechos del proceso del servidor COM. Sin embargo, es posible que necesite usar 'CoInitializeSecurity()' para permitir que los procesos de derechos inferiores se conecten y usen su servidor COM. –

+0

Ok. ¿Pero esta solución parece razonable desde el punto de vista de la simplificación del uso del módulo? O alguna otra opción? – AlexeyDaryin

Cuestiones relacionadas