2012-02-06 11 views
8

sto preparando un modulo di Delphi, che imposta un gancio in un thread per registrare una macro:SetWindowsHookEx per WH_JOURNALRECORD fallisce sotto Vista/Windows 7

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

che funziona bene su WinXP, ma su Vista/Windows 7 fallisce con ERROR_ACCESS_DENIED. Ho trovato in Google (this) riferimento (that). La citazione:

Un processo di privilegi inferiore non può: ... Utilizzare ganci di giornale per monitorare un processo di privilegio più elevato .

provato senza successo: applicazione

  1. Esegui come amministratore. Probabilmente il thread è stato avviato con privilegi inferiori al thread principale (anche se non sono sicuro al 100% )
  2. Impersonare il thread con il contesto di sicurezza dell'amministratore non aiuta neanche.

L'esempio di codice:

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 e ImpersonateLoggedOnUser eseguire senza errori.

Altre possibilità da provare:

  1. Accendere UAC OFF in modo permanente. Questo aiuta, ma non posso forzare gli utenti del modulo a farlo.
  2. Un cliente del modulo firma un'applicazione e la inserisce in una posizione attendibile . Non provato, ma questo complica radicalmente l'utilizzo del modulo per gli utenti.
  3. Inserire il modulo in un'applicazione firmata e distribuire EXE. Che interromperà alcune funzionalità di base.

Potrebbe per favore mostrare il codice che sta impostando il gancio sotto Visa/Windows 7 o suggerire la soluzione di lavoro?

+2

È necessario incorporare un manifest per chiedere all'utente il permesso di elevazione. Sospetto che cada nella categoria "radicalmente complicata". –

risposta

8

Leggere di nuovo la sezione "Isolamento dei privilegi dell'interfaccia utente" di that article. Si riferisce ai livelli di integrità , non autorizzazioni utente. Ecco perché impersonare un altro utente non risolve il problema. Il livello di integrità viene stabilito all'avvio del processo e non può essere modificato dinamicamente nel codice.

User Interface Privilege Isolation (UIPI) è uno dei meccanismi che aiuta isolare i processi in esecuzione come amministratore completo da processi in esecuzione come un conto inferiore a un amministratore del stesso desktop interattivo. UIPI è specifico per la finestra e il sottosistema grafico , noto come USER, che supporta i controlli dell'interfaccia utente di windows .UIPI impedisce un'applicazione con privilegi più bassi da utilizzando i messaggi di Windows per inviare l'input da un processo a un processo privilegiato superiore. L'invio dell'input da un processo a un altro consente a un processo di immettere l'input in un altro processo senza che l'utente fornisca le azioni della tastiera o del mouse.

Windows Vista implementa UIPI definendo un set di livelli di privilegio dell'interfaccia utente in modo gerarchico. La natura dei livelli è tale che i livelli di privilegi più elevati possono inviare messaggi della finestra alle applicazioni eseguite a livelli inferiori. Tuttavia, i livelli inferiori non possono inviare i messaggi della finestra alle finestre delle applicazioni eseguite a livelli più alti.

Il livello di privilegio dell'interfaccia utente è a livello di processo. Quando un processo viene inizializzato, il sottosistema utente chiama nel sottosistema di sicurezza per determinare il livello di integrità del desktop assegnato nel token di accesso di sicurezza del processo . Il livello di integrità del desktop viene impostato da il sottosistema di sicurezza quando il processo viene creato e non cambia . Pertanto, il livello di privilegio dell'interfaccia utente viene impostato anche dal sottosistema utente quando il processo viene creato e non cambia.

Tutte le applicazioni eseguite da un utente standard hanno la stessa interfaccia utente con il livello di privilegio . UIPI non interferisce o modifica il comportamento della messaggistica della finestra tra le applicazioni con lo stesso livello di privilegio. UIPI entra in vigore per un utente membro del gruppo di amministratori e può eseguire applicazioni come utente standard (a volte indicato come processo con un token di accesso filtrato) e anche processi in esecuzione con un amministratore completo accedi token su lo stesso desktop. UIPI impedisce ai processi di privilegi inferiori da l'accesso a processi di privilegi più elevati bloccando il comportamento elencato di seguito.

  • Utilizzare ganci di giornale per monitorare un processo di privilegi più elevato.

Secondo this article, la vostra applicazione ha bisogno di un manifesto UAC che specifica sia requestedExecutionLevel=requireAdministrator e uiAccess=True. Il diritto uiAccess è importante:

Specificando uiAccess =”true” in attributo requestedPrivileges, l'applicazione sta dichiarando l'obbligo di bypassare le restrizioni UIPI ... Un processo che viene lanciato con diritti di accesso all'interfaccia utente:

  • Può impostare ganci di giornale.
+0

Remy, grazie molte per la risposta. Supponiamo che abbia il server COM fuori processo - firmato e manifestato con uiAccess = True. Il server imposta le procedure di hook e scambia i dati con l'applicazione utente tramite i callback COM. Quindi, tutta l'elaborazione viene ancora eseguita dall'applicazione utente.Domanda: quando un'applicazione UI standard (non firmata e in esecuzione senza elevazione dei diritti) utilizza un tale server COM, il server sarà comunque in grado di impostare i ganci del journal? – AlexeyDaryin

+0

@AlexeyDaryin: come suggerisce il nome, un server COM out-of-process viene eseguito nel proprio processo. I diritti del processo dell'app standard non avranno alcun effetto sui diritti del processo del server COM. Potrebbe essere necessario utilizzare 'CoInitializeSecurity()' per consentire ai processi con diritti inferiori di connettersi e utilizzare il server COM, tuttavia. –

+0

Ok. Ma questa soluzione sembra ragionevole dal punto di vista della semplificazione dell'utilizzo del modulo? O altre opzioni? – AlexeyDaryin

Problemi correlati