Process Invincibility

Huge area to cover, we have assembled and written tutorials that have proven helpful over time.

Process Invincibility

Postby Subsky » Mon Jan 17, 2005 7:13 am

Process Invincibility


To make a process invincible on Windows Nt, 2000 and XP, we can intercept the system service- ZwTerminateProcess(), called each time an application or driver requests to terminate a process. Since we are doing this in Kernel Mode- the central part of the operating system, hooking ZwTerminateProcess() in ntoskrnl.exe will catch the call from any single application, dll or driver.

Upon modifying the correct pointer in the system service table for ZwTerminateProcess(), we’ll have changed it to the address of our hook procedure. Inside the new procedure we must do a bit of process checking- If indeed a process is trying to terminate ours we must return STATUS_ACCESS_DENIED; otherwise our hook function should make the call to the original ZwTerminateProcess() system service.

Code: Select all
NTSYSAPI NTSTATUS NTAPI ZwTerminateProcess ( IN HANDLE ProcessHandle OPTIONAL, IN NTSTATUS ExitStatus );
The problem is that once we’ve hooked ZwTerminateProcess(), we don't actually know the name of the process trying to being terminated- we are only given a HANDLE ProcessHandle to it in the first argument. Unlike in user-mode, we can't rely on the API functions provided by the PSAPI [.dlls aren't linked to drivers operating in Kernel Mode] such as GetModuleBaseName() in PSAPI.DLL to get the name of the process the HANDLE refers to. To overcome this, one particularly useful Kernel Support Routine [Function provided by the Kernel] is used directly.
Code: Select all
NTSTATUS ObReferenceObjectByHandle( IN HANDLE Handle, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType OPTIONAL, IN KPROCESSOR_MODE AccessMode, OUT PVOID *Object, OUT POBJECT_HANDLE_INFORMATION HandleInformation OPTIONAL );
When you call ObReferenceObjectByHandle() you obtain a pointer to a HANDLE's related _EPROCESS structure;
Code: Select all
typedef struct _EPROCESS { KPROCESS Pcb; EX_PUSH_LOCK ProcessLock; ... UCHAR ImageFileName[16]; ... UCHAR PriorityClass; BOOLEAN WorkingSetAcquiredUnsafe; } EPROCESS, *PEPROCESS;
And there it is; UCHAR ImageFileName[16]- the start address in memory of the name of the process being terminated.

All we need to do now is perform a simple memory comparison- checking to see that it is indeed our application trying to be terminated. If so we simply return STATUS_ACCESS_DENIED.
Code: Select all
if(0 == memcmp(&pEProcess->ImageFileName[0], ExeName, sizeof(ExeName))) { return STATUS_ACCESS_DENIED; }
Once in memory, your process is invincible and can not be terminated until the power is turned off. Cool huh? :)
Subsky
n00b
 
Posts: 2
Joined: Sun Jan 16, 2005 5:30 am

Return to “%s” Windows Tutorials

Who is online

Users browsing this forum: No registered users and 0 guests

cron