Hooking TerminateProcess & Getting Info From The Handle It Supplies
If you want to stop a process from being terminated, one way is to hook into TerminateProcess (or NtTerminateProcess). If the process is terminating itself (because you closed its window, for example), the handle supplied to those functions is NULL, so you can find out what executable is being terminated using GetCurrentProcess() & GetModuleFileNameEx(). As GetCurrentProcess() returns a pseudo-handle, you can access it with no problems.
If one process is terminating another, though, the handle supplied is not NULL. It represents the process being terminated. The problem is, you can't get information about that process. You can simply return a code saying "access denied" instead of calling the original [Nt]TerminateProcess(), but that blanket stops all processes from terminating others - which is a bad idea.
The handle must represent something valid otherwise Ter开发者_高级运维minateProcess wouldn't be able to do anything useful with it - but I can't even call GetProcessId() on it, I get ERROR_INVALID_HANDLE (or ERROR_ACCESS_DENIED). I've tried various methods I've collected from the help and from online, including gaining the debug privilege (success) and DuplicateHandle() (same error) and ZwQueryInformationProcess() to get the ID (STATUS_ACCESS_DENIED). I can't even enumerate processes because they return IDs, and I can't get the ID, and OpenProcess() always returns a fresh handle, so I can't compare handles.
I can only assume the handle has PROCESS_TERMINATE right and nothing else. I know that Vista and higher have protected processes due to Digital Rights Management, but I'm using ProcessExplorer as my guinea pig so it's definitely not a media application!
Does anyone know how else I might be able to get any kind of information about the process being terminated from this handle?
It's just an ordinary process handle. The question is, in which process is your hook function executing? If it's the calling process, the handle can be used as-is for GetProcessId or NtQueryInformationProcess. If not, you need to call DuplicateHandle to duplicate the handle into your process.
If you're getting access denied errors, it may be because the process handle only has PROCESS_TERMINATE access. In that case, use DuplicateHandle to "re-open" the process with PROCESS_QUERY_(LIMITED_)INFORMATION access.
精彩评论