WH_JOURNALRECORD 的 SetWindowsHookEx 在 Vista/Windows 7 下失败 [英] SetWindowsHookEx for WH_JOURNALRECORD fails under Vista/Windows 7

查看:36
本文介绍了WH_JOURNALRECORD 的 SetWindowsHookEx 在 Vista/Windows 7 下失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am preparing a Delphi module, which sets a hook in a thread to record a macro:

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

这在 WinXP 上运行良好,但在 Vista/Windows 7 上失败并显示 ERROR_ACCESS_DENIED.我在 Google (这个)引用(那个).引用:

That works fine on WinXP, but on Vista/Windows 7 fails with ERROR_ACCESS_DENIED. I have found in Google (this) referring (that). The quote:

较低权限的进程不能: ... 使用日志挂钩来监视更高权限的进程.

A lower privilege process cannot: … Use Journal hooks to monitor a higher privilege process.

试过了,没有成功:

  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);

LogonUserImpersonateLoggedOnUser 执行时不会出错.

LogonUser and ImpersonateLoggedOnUser execute without errors.

其他尝试的可能性:

  1. 永久关闭 UAC.这有帮助,但我不能强制模块用户这样做.
  2. 模块客户签署应用程序并将其放入受信任的地点.没有尝试过,但这使模块从根本上复杂化供用户使用.
  3. 将模块放入某个签名的应用程序并分发EXE.那会破坏一些核心功能.

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

Could you please show the code that is setting the hook under Visa / Windows 7 or suggest the working solution ?

推荐答案

阅读 那篇文章再仔细点.它指的是完整性级别,而不是用户权限.这就是为什么冒充另一个用户并不能解决问题的原因.完整性级别是在进程首次启动时建立的,不能在代码中动态更改.

Read the "User Interface Privilege Isolation" section of that article again more carefully. It is referring to integrity levels, not user permissions. That is why impersonating another user does not solve the problem. The integrity level is established when the process first starts and cannot be changed dynamically in code.

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

User Interface Privilege Isolation (UIPI) is one of the mechanisms that helps isolate processes running as a full administrator from processes running as an account lower than an administrator on the same interactive desktop. UIPI is specific to the windowing and graphics subsystem, known as USER, that supports windows and user interface controls. UIPI prevents a lower privilege application from using Windows messages to send input from one process to a higher privilege process. Sending input from one process to another allows a process to inject input into another process without the user providing keyboard or mouse actions.

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

Windows Vista implements UIPI by defining a set of user interface privilege levels in a hierarchical fashion. The nature of the levels is such that higher privilege levels can send window messages to applications running at lower levels. However, lower levels cannot send window messages to application windows running at higher levels.

用户界面权限级别为进程级别.当一个进程初始化,用户子系统调用安全子系统来确定在进程的安全访问令牌.桌面完整性级别由进程创建时的安全子系统改变.因此,用户界面权限级别也由用户子系统在进程创建且未更改时.

标准用户运行的所有应用程序都具有相同的用户界面特权级别.UIPI 不会干扰或改变相同权限级别的应用程序之间的窗口消息传递.UIPI 对属于管理员组,并且可能将应用程序作为标准运行用户(有时称为具有过滤访问令牌的进程)以及使用完整管理员访问令牌运行的进程同一个桌面. UIPI 阻止较低权限的进程通过阻止列出的行为来访问更高权限的进程下面.

All applications run by a standard user have the same user interface privilege level. UIPI does not interfere or change the behavior of window messaging between applications at the same privilege level. UIPI comes into effect for a user who is a member of the administrators group and may be running applications as a standard user (sometimes referred to as a process with a filtered access token) and also processes running with a full administrator access token on the same desktop. UIPI prevents lower privilege processes from accessing higher privilege processes by blocking the behavior listed below.

  • 使用日志挂钩来监控更高权限的进程.

根据这篇文章,您的应用需要一个同时指定 的 UAC 清单requestedExecutionLevel=requireAdministratoruiAccess=True.UIAccess 权限很重要:

According to this article, your app needs a UAC manifest that specifies both requestedExecutionLevel=requireAdministrator and uiAccess=True. The UIAccess right is important:

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

By specifying UIAccess="true" in the requestedPrivileges attribute, the application is stating a requirement to bypass UIPI restrictions ... A process that is launched with UIAccess rights:

  • 可以设置日志挂钩.

这篇关于WH_JOURNALRECORD 的 SetWindowsHookEx 在 Vista/Windows 7 下失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆