可以在运行时禁用使用SetWindowsHookEx创建的钩子吗?

5
如果一个应用程序(例如我的应用程序或外部进程)调用了SetWindowsHookEx,那么我能否取消挂钩?请记住,不是我首先创建的挂钩,因此我没有任何原始挂钩的变量或指针。

1
虽然我现在没有解决方案,但我认为这应该是可能的。基本上,每个反间谍软件/病毒扫描器都必须使用此功能或等效功能,例如查找和取消挂钩键盘记录器。好问题! - merkuro
刚发现一个叫做“Rootkit Unhooker 3.8”的程序。它基本上可以做你想要的事情,但仍然没有长篇代码示例:http://www.rootkit.com/newsread.php?newsid=902 尽管我认为这个页面是合法的,但你可能想从一个更可信赖的网站下载旧版本。 - merkuro
我认为rootkit不关心HHOOKs。 它们深入系统的程度让我怀疑它们是否需要那种特定的机制。 - Kevin Montrose
3个回答

5
没有,不行。
在以前(NT 之前的时代),你可能可以通过获取 HHOOK 来玩一些游戏,因为返回的 HHOOK 是一个链式钩子链接,可以被调用。即使那时也不确定是否可能。
今天,Windows 不再委托您调用链中的下一个钩子(因此弃用了 CallNextHookEx 的参数),而 HHOOKs 也不再让您访问您没有注册的钩子。
更恰当地说,没有一种好的且受支持的方法来做到这一点。
你可以安装一个rootkit,深入了解Windows内部并找到钩子链的方法;但显然这将是荒谬的 - 也很危险。
通过一些API hooking解决方案(例如Detours),以及SetWindowsHookExCallNextHookEx的钩子,可以使符合先前NT约定的应用程序实现大部分功能。其要点是在调用SetWindowsHookEx后立即取消新的钩子,取消任何传递的钩子(不是你自己的)以调用CallNextHookEx。为了保证“干净”的应用程序,您还必须模拟许多事件以强制执行任何已调用的钩子,以便它们可以被取消挂接。此外,只要遇到在过去8年中编写的向CallNextHookEx传递NULL的应用程序,此方案就会失败。
因此,即使从技术上讲(也许)可以取消挂钩未注册的HHOOKS,但您最好尝试以不同的、不那么脆弱的方式完成您想要的任何事情。

1

我认为你不能这样做。你需要使用 SetWindowsHookEx() 注册钩子的句柄,以便你可以使用 UnhookWindowsHookEx() 取消注册它。

顺便说一下,如果你在任何其他钩子被注册之前(即在应用程序启动期间)能够创建自己的钩子,那么你可以在该钩子中选择不调用 CallNextHookEx(),从而防止调用后续的钩子。可能值得一试。我怀疑这可能并不适用于所有类型的钩子。


1

实际上,我认为我发现了是的,这是可能的。挂钩CallNextHook将给您挂钩的挂钩ID,您可以使用它来取消挂钩。


1
出于专业好奇心和对“正确”答案的渴望,我们能否在这个回答中得到一些相关代码? - Kevin Montrose
刚刚使用了一个名为Deviare的API,你可以搜索一下。它让你可以在5行代码中挂钩函数,所以你只需要挂钩CallNextHook,并且如果hook不等于0,则调用UnhookWindowsEx()。 - Jorge Branco
2
自Windows Me以来,您不需要传递钩子到CallNextHookEx,因此对于某些应用程序,这将会出现问题。此外,在取消挂钩之前,必须至少运行一次钩子,因此您无法可靠地说“此应用程序未被[此处的钩子类型]挂钩”。无论如何,我会更新我的答案,使其更加“完整”。 - Kevin Montrose

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接