SetWindowsHookEx для WH_JOURNALRECORD не работает в Vista / Windows 7 - PullRequest
8 голосов
/ 06 февраля 2012

Я готовлю модуль Delphi, который устанавливает ловушку в потоке для записи макроса:

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

Это прекрасно работает в WinXP, но в Vista / Windows 7 не работает с ERROR_ACCESS_DENIED. Я нашел в Google ( это ) ссылаясь (, что ). Цитата:

Процесс с более низким уровнем привилегий не может:… использовать журнальные ловушки для мониторинга процесс с более высокими привилегиями.

Попытка без успеха:

  1. Запустить приложение от имени администратора. Возможно, поток запущен с более низкими привилегиями, чем основной поток (хотя я не на 100% уверен)
  2. Олицетворение потока в контексте безопасности администратора тоже не помогает.

Пример кода:

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 и ImpersonateLoggedOnUser выполняются без ошибок.

Другие возможности попробовать:

  1. Выключить UAC постоянно. Это помогает, но я не могу заставить модуль пользователи для этого.
  2. Клиент модуля подписывает заявку и помещает ее в доверенное место нахождения. Не пробовал, но это радикально усложняет модуль использование для пользователей.
  3. Поместите модуль в какое-нибудь подписанное приложение и раздайте EXE. Тот сломает некоторые основные функции.

Не могли бы вы показать код, который устанавливает ловушку под Visa / Windows 7 или предложить рабочее решение?

1 Ответ

8 голосов
/ 07 февраля 2012

Прочтите раздел «Изоляция прав интерфейса пользователя» этой статьи еще раз более внимательно.Это относится к уровням целостности , а не пользовательских разрешений .Вот почему выдача себя за другого пользователя не решает проблему. уровень целостности устанавливается при первом запуске процесса и не может быть динамически изменен в коде.

Изоляция привилегий пользовательского интерфейса (UIPI) - это один из механизмов, который помогает изолировать запущенные процессыкак полный администратор из процессов, выполняющихся под учетной записью ниже, чем администратор на том же интерактивном рабочем столе.UIPI специфичен для оконной и графической подсистемы, известной как USER, которая поддерживает окна и элементы управления пользовательского интерфейса.UIPI не позволяет приложению с более низким уровнем привилегий использовать сообщения Windows для отправки входных данных от одного процесса процессу с более высоким уровнем привилегий.Отправка ввода от одного процесса к другому позволяет процессу вводить ввод в другой процесс без предоставления пользователем действий клавиатуры или мыши.

В Windows Vista реализован UIPI путем определения набора уровней привилегий пользовательского интерфейса в иерархической форме.Природа уровней такова, что более высокие уровни привилегий могут отправлять оконные сообщения приложениям, работающим на более низких уровнях.Однако нижние уровни не могут отправлять оконные сообщения окнам приложений, работающим на более высоких уровнях.

Уровень привилегий интерфейса пользователя находится на уровне процесса.Когда процесс инициализируется, подсистема «Пользователь» вызывает подсистему безопасности, чтобы определить уровень целостности рабочего стола, назначенный в маркере доступа процесса.Уровень целостности рабочего стола устанавливается подсистемой безопасности при создании процесса и не изменяется.Поэтому уровень привилегий пользовательского интерфейса также устанавливается подсистемой «Пользователь» при создании процесса и не изменяется.

Все приложения, запускаемые стандартным пользователем, имеют одинаковый уровень привилегий пользовательского интерфейса.UIPI не мешает и не изменяет поведение оконного обмена сообщениями между приложениями с одинаковым уровнем привилегий. UIPI вступает в силу для пользователя, который является членом группы администраторов и может запускать приложения в качестве обычного пользователя (иногда его называют процессом с токеном фильтрованного доступа), а также процессов, запущенных с токеном полного доступа администратора.на том же рабочем столе. UIPI не позволяет процессам с более низкими привилегиями получать доступ к процессам с более высокими привилегиями, блокируя действия, перечисленные ниже.

  • Использование перехватчиков журнала для мониторинга процесса с более высокими привилегиями.

В соответствии с этой статьей вашему приложению необходим манифест UAC, в котором указаны requestedExecutionLevel=requireAdministrator и uiAccess=True.Право UIAccess важно:

Указав UIAccess = ”true” в атрибуте requiredPrivileges, приложение устанавливает требование обойти ограничения UIPI ... Процесс, который запускается с правами UIAccess:

  • Можно установить журнальные крючки.
...