Today I’m going to explain to you how you could protect your process by hooking ZwOpenProcess. It may be easy, but damn it took me sometime to figure it out! I would assume that you guys know the basics of kernel driver development and know the basics of hooking. If not, go get yourself Rootkits: Subverting the Windows Kernel or Professional Rootkits But of course if you don’t want to spend money on them, search the internet =) Both books helped me a lot, also you may want to take a look to the Rootkit website Rootkit
ZwOpenProcess opens a handle to a desired process. With a handle you can do many things, but in this post we are going to talk about how to deny access when someone is trying to terminate your protected process. You have probably encounter such a hook since almost every anti-virus/firewall uses them to prevent malicious software from terminating them.
Let’s take a look at ZwOpenProcess:
ZwOpenProcess (
OUT PHANDLE ProcessHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes,
IN PCLIENT_ID ClientId OPTIONAL);
What we want here is ClientsId since that’s a pointer to the Client ID, we could use it to check if a application is trying to get a handle to our protected process PID. Here’s a code snippet:
NTSTATUS NewZwOpenProcess(
OUT PHANDLE ProcessHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes,
IN PCLIENT_ID ClientId OPTIONAL)
{
HANDLE ProcessId;__try /*we do this to avoid crashes*/
{ProcessId = ClientId->UniqueProcess;
}
__except(EXCEPTION_EXECUTE_HANDLER) /*we do this to avoid crashes*/
{
/*DbgPrint(“Exception”)*/
return STATUS_INVALID_PARAMETER;}
if (ProcessId == (HANDLE)2816) /*Check if the PID matches our protected process PID*/
{/*DbgPrint(“Access Denied!”);*/
return STATUS_ACCESS_DENIED; /*What we want, access denied.*/
}else /*Important, if you don’t do this your system will and and crash/BSOD*/
return OldZwOpenProcess(ProcessHandle, DesiredAccess,ObjectAttributes, ClientId);
}
In my example I use “firefox.exe”, as you can see I got Access Denied and also notice that Process Explorer was unable to list the loaded modules in our process.
Now try to kill your protected process, it most probably failed. Why most probably? Because your process is not invisible. There’s some tools that can still terminate your process. Also, a user can simply check if ZwOpenProcess is hooked in the SDT, and recover it, therefor your hook is dead.
Important!!! My example is not complete, it’s kinda of a “proof of concept” I hardcoded the PID but it shouldn’t be hard to pass the PID from the userland, even get the PID from the kernel if you want. The source code can be downloaded from the link below. If you find any errors or bug, please let me know.
Later.
EDIT: Well I have received a e-mail asking how to hook Nt* functions. The concept is still the same, but there’s some changes, I may write another article on that if you guys want.

May 9, 2008 at 9:13 am
Hi
Nice article very impressive i would lik to know more about the Kernel Hooking
can you help me ??
Thanks
Jegajith.P.T
May 12, 2008 at 10:48 am
HI
Can you please send me the code jegajith@gmail.com
June 17, 2009 at 12:20 pm
hi great article
Is this work for vista or can you tell me the way to protect exe on vista?
Thank you