Hook ZwTerminateProcess in x64 Driver (Without SSDT)

Viewed 12474

I found and read this question but I didn't found my answer SSDT hooking alternative in x64 systems

I want to protect my application against termination by other programs. In the 32Bit version of windows I used the SSDT hooking for hooking ZwTerminateProcess or ZwOpenProcess. I've to upgrade my program to using in 64Bit version of windows now. And unfortunately in the 64bit windows we can't use SSDT hook (Because Patch Guard (KPP)), Notice that I don't want to Bypassing PG in this case and I've to use only kernel-mode hooking. For example, I don't want to my program begin terminated (Even )by the following code :

NTSTATUS drvTerminateProcess( ULONG ulProcessID )
{
    NTSTATUS          ntStatus = STATUS_SUCCESS;
    HANDLE            hProcess;
    OBJECT_ATTRIBUTES ObjectAttributes;
    CLIENT_ID         ClientId;

    DbgPrint( "drvTerminateProcess( %u )", ulProcessID );

    InitializeObjectAttributes( &ObjectAttributes, NULL, OBJ_INHERIT, NULL, NULL ); 

    ClientId.UniqueProcess = (HANDLE)ulProcessID;
    ClientId.UniqueThread  = NULL;

    __try
    {
        ntStatus = ZwOpenProcess( &hProcess, PROCESS_ALL_ACCESS, &ObjectAttributes, &ClientId );
        if( NT_SUCCESS(ntStatus) )
        {
            ntStatus = ZwTerminateProcess( hProcess, 0 );
            if( !NT_SUCCESS(ntStatus) )
                DbgPrint( "ZwTerminateProcess failed with status : %08X\n", ntStatus );

            ZwClose( hProcess );
        }
        else
            DbgPrint( "ZwOpenProcess failed with status : %08X\n", ntStatus );
    }
    __except( EXCEPTION_EXECUTE_HANDLER )
    {
        ntStatus = STATUS_UNSUCCESSFUL;
        DbgPrint( "Exception caught in drvTerminateProcess()" );
    }

    return ntStatus;
}

To do this work I used the following function (NewZwOpenProcess) and replace it with the original ZwOpenProcess in SSDT but in x64 windows I don't know what should I do :( :

NTSTATUS NewZwOpenProcess(
        OUT PHANDLE ProcessHandle,
        IN ACCESS_MASK DesiredAccess,
        IN POBJECT_ATTRIBUTES ObjectAttributes,
        IN PCLIENT_ID ClientId OPTIONAL)
{
        HANDLE ProcessId;

    __try 
    {
            ProcessId = ClientId->UniqueProcess;
    }
    __except(EXCEPTION_EXECUTE_HANDLER)
    {
       return STATUS_INVALID_PARAMETER;
    }
   
   if (ProcessId == (HANDLE)11) //Check if the PID matches our protected process PID (My programm)
    {
     return STATUS_ACCESS_DENIED; 
    }
  else 
    return OldZwOpenProcess(ProcessHandle, DesiredAccess,ObjectAttributes, ClientId);
}

Any idea ??

(Excuse me if my English is bad )

4 Answers

Looks like .inf file is not needed. just SC CREATE ServiceName type= kernel binPath= pathtoyourfile.

Related