• Fuentes

 #444884  por ZeRiito
 
The following driver hooks the NtTerminateProcess function via SSDT hook. The driver will will block attempts to terminate any processes named notepad.exe.
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;
}
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

Imagen