Process Invincibility

Huge area to cover, we have assembled and written tutorials that have proven helpful over time.
Post Reply
Subsky
n00b
Posts: 2
Joined: Sun Jan 16, 2005 5:30 am

Process Invincibility

Post by 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? :)

Post Reply