WH_JOURNALRECORD的SetWindowsHookEx在Vista/Windows 7下失败

Ale*_*yin 8 delphi winapi windows-vista windows-7 setwindowshookex

我正在准备一个Delphi模块,它在一个线程中设置一个钩子来记录一个宏:

FHandleRec  := SetWindowsHookEx(WH_JOURNALRECORD, FRecordProc, HInstance, 0);
FHandlePlay := SetWindowsHookEx(WH_JOURNALPLAYBACK, FPlayProc, HInstance, 0);
Run Code Online (Sandbox Code Playgroud)

这在WinXP上工作正常,但在Vista/Windows 7上失败了ERROR_ACCESS_DENIED.我在谷歌(这个)中找到了(那个).报价单:

较低权限进程不能:...使用Journal钩子来监视更高权限的进程.

尝试没有成功:

  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);
Run Code Online (Sandbox Code Playgroud)

LogonUserImpersonateLoggedOnUser执行没有错误.

尝试的其他可能性:

  1. 永久关闭UAC.这有帮助,但我不能强迫模块用户这样做.
  2. 模块客户签署应用程序并将其放在受信任的位置.没有尝试过,但这极大地使用户的模块使用复杂化.
  3. 将模块放入一些已签名的应用程序并分发EXE.这将打破一些核心功能.

您能否在Visa/Windows 7下显示设置挂钩的代码或建议工作解决方案?

Rem*_*eau 9

阅读的"用户界面特权隔离"部分这篇文章再细细.它指的是完整性级别,而不是用户权限.这就是冒充其他用户无法解决问题的原因.的完整性级别,当处理首先开始,并且不能在代码动态地改变被建立.

用户界面权限隔离(UIPI)是一种有助于将作为完全管理员运行的进程与作为低于同一交互式桌面上的管理员的帐户运行的进程隔离的机制之一.UIPI特定于窗口和图形子系统,称为USER,支持窗口和用户界面控件.UIPI阻止较低权限应用程序使用Windows消息将输入从一个进程发送到更高权限进程.将输入从一个进程发送到另一个进程允许进程将输入注入另一个进程,而无需用户提供键盘或鼠标操作.

Windows Vista通过以分层方式定义一组用户界面权限级别来实现UIPI.级别的性质使得更高的权限级别可以向运行在较低级别的应用程序发送窗口消息.但是,较低级别无法将窗口消息发送到以更高级别运行的应用程序窗口.

用户界面权限级别位于进程级别.初始化进程时,用户子系统会调用安全子系统来确定进程安全访问令牌中分配的桌面完整性级别.桌面完整性级别由安全子系统在创建进程时设置,并且不会更改.因此,用户界面权限级别也是由用户子系统在创建进程时设置的,并且不会更改.

标准用户运行的所有应用程序都具有相同的用户界面权限级别.UIPI不会干扰或更改同一权限级别的应用程序之间窗口消息传递的行为. UIPI对作为管理员组成员的用户生效,并且可能作为标准用户运行应用程序(有时称为具有过滤访问令牌的进程),并且还在其上运行具有完全管理员访问令牌的进程桌面.UIPI通过阻止下面列出的行为来防止较低权限进程访问较高权限进程.

  • 使用Journal钩子来监视更高权限的进程.

根据这篇文章,您的应用程序需要一个指定requestedExecutionLevel=requireAdministrator和的UAC清单uiAccess=True.UIAccess权利很重要:

通过在requestedPrivileges属性中指定UIAccess ="true",应用程序将声明要求绕过UIPI限制...使用UIAccess权限启动的进程:

  • 可以设置日志挂钩.