【问题标题】:Hooking TerminateProcess & Getting Info From The Handle It Supplies挂钩 TerminateProcess 并从它提供的句柄中获取信息
【发布时间】:2010-11-07 11:21:54
【问题描述】:

如果你想阻止一个进程被终止,一种方法是挂接到 TerminateProcess(或 NtTerminateProcess)。如果进程正在终止自身(例如,因为您关闭了它的窗口),则提供给这些函数的句柄为 NULL,因此您可以使用 GetCurrentProcess() 和 GetModuleFileNameEx() 找出正在终止的可执行文件。由于 GetCurrentProcess() 返回一个伪句柄,您可以毫无问题地访问它。

但是,如果一个进程正在终止另一个进程,则提供的句柄不是 NULL。它表示正在终止的进程。问题是,您无法获得有关该过程的信息。您可以简单地返回一个“拒绝访问”的代码,而不是调用原始的 [Nt]TerminateProcess(),但是该毯子会阻止所有进程终止其他进程 - 这是一个坏主意。

句柄必须代表有效的东西,否则 TerminateProcess 将无法用它做任何有用的事情——但我什至不能在它上面调用 GetProcessId(),我得到 ERROR_INVALID_HANDLE(或 ERROR_ACCESS_DENIED)。我尝试了从帮助和在线收集的各种方法,包括获得调试权限(成功)和 DuplicateHandle()(同样的错误)和 ZwQueryInformationProcess() 来获取 ID(STATUS_ACCESS_DENIED)。我什至无法枚举进程,因为它们返回 ID,而且我无法获取 ID,而且 OpenProcess() 总是返回一个新的句柄,所以我无法比较句柄。

我只能假设句柄有 PROCESS_TERMINATE 正确,没有别的。我知道由于数字版权管理,Vista 和更高版本具有受保护的进程,但我使用 ProcessExplorer 作为我的试验品,所以它绝对不是媒体应用程序!

有谁知道我还能如何获得有关从此句柄终止的进程的任何信息?

【问题讨论】:

    标签: process handle terminate


    【解决方案1】:

    它只是一个普通的进程句柄。问题是,你的钩子函数在哪个进程中执行?如果是调用进程,句柄可以直接用于GetProcessId或NtQueryInformationProcess。如果没有,您需要调用 DuplicateHandle 将句柄复制到您的进程中。

    如果您收到拒绝访问错误,可能是因为进程句柄只有 PROCESS_TERMINATE 访问权限。在这种情况下,请使用 DuplicateHandle 以 PROCESS_QUERY_(LIMITED_)INFORMATION 访问权限“重新打开”进程。

    【讨论】:

    • 我在问题中确实提到我已经尝试过 DuplicateHandle() (试图获得足够的访问权限),但无济于事。由于钩子被注入到每个进程中,并且只能捕获同一进程对 NTDLL 的调用,因此只能在执行终止的应用程序的上下文中调用它。例如,如果 ProcessExplorer 终止了一个应用程序,则触发的是映射到 ProcessExplorer 的钩子代码,您是否不同意它应该是 ProcessExplorer 自己的上下文?它不能是目标应用程序的,因为它没有进行 TerminateProcess 调用...
    • 我应该澄清一下,我使用的是 AppInit_DLLs 挂钩方法,而不是系统范围的挂钩。我忘了澄清我的钩子代码只在调用终止另一个的应用程序中执行。
    • 我提到句柄的原因是因为您没有指定挂钩是如何完成的,并且您提到了无效句柄错误。使用 DuplicateHandle 到底有什么问题?也许你可以发布一些代码......
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-28
    • 1970-01-01
    • 2022-07-18
    • 2021-06-20
    • 2021-09-16
    • 1970-01-01
    相关资源
    最近更新 更多