如果要阻止进程终止,一种方法是挂钩到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作为我的豚鼠,因此它绝对不是媒体应用程序!
有谁知道我怎么能够获得有关从此句柄终止进程的任何信息?
答案 0 :(得分:1)
这只是一个普通的流程句柄。问题是,你的钩子函数在哪个进程中执行?如果它是调用进程,则句柄可以按原样用于GetProcessId或NtQueryInformationProcess。如果没有,您需要调用DuplicateHandle将句柄复制到您的过程中。
如果您获得访问被拒绝错误,可能是因为进程句柄只有PROCESS_TERMINATE访问权限。在这种情况下,使用DuplicateHandle通过PROCESS_QUERY_(LIMITED_)INFORMATION访问“重新打开”该过程。