WH_JOURRNALRECORD 的 SetWindowsHookEx 在 Vista/Windows 7 下失败
我正在准备一个 Delphi 模块,它在线程中设置一个钩子来记录宏:
FHandleRec := SetWindowsHookEx(WH_JOURNALRECORD, FRecordProc, HInstance, 0);
FHandlePlay := SetWindowsHookEx(WH_JOURNALPLAYBACK, FPlayProc, HInstance, 0);
在 WinXP 上工作正常,但在 Vista/Windows 7 上失败,并显示 ERROR_ACCESS_DENIED
。 我在 Google 中找到了(这)指的是(那个)。报价:
较低权限的进程不能:...使用日志挂钩来监视 更高权限的进程。
尝试未成功:
- 以管理员身份运行应用程序。可能线程已启动 权限低于主线程(虽然我不是 100% 当然)
- 使用管理员安全上下文模拟线程 也没有帮助。
代码示例:
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
执行时没有错误。
其他可以尝试的可能性:
- 永久关闭 UAC。这有帮助,但我无法强制该模块 用户这样做。
- 模块客户签署应用程序并将其放入受信任的应用程序中 地点。没有尝试过,但这使模块变得非常复杂 供用户使用。
- 将模块放入某个已签名的应用程序中并分发 EXE。那 会破坏一些核心功能。
您能否显示在 Visa/Windows 7 下设置挂钩的代码或建议工作解决方案?
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);
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.
Tried without success:
- Run application as administrator. Probably the thread is started
with lower privileges than the main thread (though I am not 100%
sure) - Impersonating the thread with administrator security context
doesn’t help either.
The code sample:
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
and ImpersonateLoggedOnUser
execute without errors.
Other possibilities to try:
- Turn UAC OFF permanently. This helps, but I cannot force the module
users to do that. - A module customer signs an application and put it in a trusted
location. Not tried that, but that radically complicates the module
usage for the users. - Put the module into some signed application and distribute EXE. That
will break some core functionality.
Could you please show the code that is setting the hook under Visa / Windows 7 or suggest the working solution ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
更仔细地再次阅读该文章的“用户界面权限隔离”部分。它指的是完整性级别,而不是用户权限。这就是为什么冒充其他用户并不能解决问题。完整性级别是在进程首次启动时建立的,并且无法在代码中动态更改。
根据本文,您的应用程序需要一个指定
requestedExecutionLevel=requireAdministrator 的 UAC 清单
和uiAccess=True
。 UIAccess 权限很重要: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.
According to this article, your app needs a UAC manifest that specifies both
requestedExecutionLevel=requireAdministrator
anduiAccess=True
. The UIAccess right is important: