C# Unkillable process kernel
Publicado: 04 Jun 2014, 17:53
The following driver hooks the NtTerminateProcess function via SSDT hook. The driver will will block attempts to terminate any processes named notepad.exe.
However, hooking NtTerminateProcess is not enough, because there are many ways to terminate a process without calling NtTerminateProcess. You should hook PsLookupProcessByProcessId if you want better protection.
Test on Windows XP

Código: Seleccionar todo
#include <ntddk.h>
typedef NTSTATUS (*pNtTerminateProcess)(HANDLE hProcess,NTSTATUS ExitStatus);
typedef struct _KSERVICE_DESCRIPTOR_TABLE
{
PULONG ServiceTableBase;
PULONG ServiceCounterTableBase;
ULONG NumberOfServices;
PUCHAR ParamTableBase;
}KSERVICE_DESCRIPTOR_TABLE,*PKSERVICE_DESCRIPTOR_TABLE;
extern PKSERVICE_DESCRIPTOR_TABLE KeServiceDescriptorTable;
LPSTR PsGetProcessImageFileName(PEPROCESS Process);
#define SYSCALL_INDEX(a)(*(PULONG)((PUCHAR)a+1))
pNtTerminateProcess fnNtTerminateProcess;
PVOID Hook(ULONG ServiceNumber,PVOID Hook)
{
PVOID OrigAddress;
__asm
{
cli
mov eax,cr0
and eax,not 0x10000
mov cr0,eax
}
OrigAddress=(PVOID)InterlockedExchange((PLONG)&KeServiceDescriptorTable->ServiceTableBase[ServiceNumber],(LONG)Hook);
__asm
{
mov eax,cr0
or eax,0x10000
mov cr0,eax
sti
}
return OrigAddress;
}
NTSTATUS HookNtTerminateProcess(HANDLE hProcess,NTSTATUS ExitStatus)
{
PEPROCESS Process;
LPSTR ProcessName;
DbgPrint("NtTerminateProcess called from %s (%u) | Exit status: %#x",PsGetProcessImageFileName(PsGetCurrentProcess()),PsGetCurrentProcessId(),ExitStatus);
if(hProcess!=NULL && hProcess!=NtCurrentProcess())
{
// Get the process object
if(NT_SUCCESS(ObReferenceObjectByHandle(hProcess,0,*PsProcessType,ExGetPreviousMode(),(PVOID*)&Process,NULL)))
{
ProcessName=PsGetProcessImageFileName(Process);
DbgPrint("Target process name: %s",ProcessName);
// Check the process name and return an error if the target process is notepad.exe
if(!_stricmp(ProcessName,"notepad.exe"))
{
DbgPrint("Access denied!");
ObDereferenceObject(Process); // Dereference the process object
return STATUS_ACCESS_DENIED; // Return error to caller
}
ObDereferenceObject(Process); // Dereference the process object
}
}
return fnNtTerminateProcess(hProcess,ExitStatus); // Call the original function
}
void Unload(PDRIVER_OBJECT pDriverObject)
{
Hook(SYSCALL_INDEX(ZwTerminateProcess),fnNtTerminateProcess);
DbgPrint("NtTerminateProcess unhooked!");
}
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject,PUNICODE_STRING pRegistryPath)
{
pDriverObject->DriverUnload=Unload;
fnNtTerminateProcess=Hook(SYSCALL_INDEX(ZwTerminateProcess),HookNtTerminateProcess);
DbgPrint("NtTerminateProcess address: %#x",fnNtTerminateProcess);
return STATUS_SUCCESS;
}
Test on Windows XP
