64-bit - 在 x64 驱动程序中 Hook ZwTerminateProcess(不带 SSDT)

标签 64-bit hook driver sql-server-data-tools kernel-mode

我找到并阅读了这个问题,但没有找到答案 SSDT hooking alternative in x64 systems

我想保护我的应用程序不被其他程序终止。在 32 位版本的 Windows 中,我使用 SSDT Hook 来 Hook ZwTerminateProcess 或 ZwOpenProcess。我现在必须将我的程序升级为在 64 位版本的 Windows 中使用。 不幸的是,在 64 位 Windows 中,我们无法使用 SSDT Hook ( Because Patch Guard (KPP) ),请注意,在这种情况下我不想绕过 PG,并且只能使用内核模式 Hook 。例如,我不希望我的程序通过以下代码开始终止(偶数):

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;
}

为了完成这项工作,我使用了以下函数 (NewZwOpenProcess) 并将其替换为 SSDT 中的原始 ZwOpenProcess,但在 x64 windows 中我不知道应该做什么做:(:

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);
}

有什么想法吗?

(如果我的英语不好,请原谅)

最佳答案

我找到了答案,我使用内核模式回调。

#include <ntddk.h>
#include <common.h>

// coded by Behrooz

VOID UnloadRoutine(IN PDRIVER_OBJECT DriverObject)
{

    FreeProcFilter();
    DbgPrintEx( DPFLTR_IHVDRIVER_ID,  DPFLTR_INFO_LEVEL,"Unloaded\n");
}

NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,  IN PUNICODE_STRING RegistryPath)
{

    NTSTATUS status = RegisterCallbackFunction();
  if(!NT_SUCCESS(status))
  {
     DbgPrintEx( DPFLTR_IHVDRIVER_ID,  DPFLTR_ERROR_LEVEL,"Faild to RegisterCallbackFunction .status : 0x%X \n",status);
  }
    DriverObject->DriverUnload = UnloadRoutine;

    DbgPrintEx( DPFLTR_IHVDRIVER_ID,  DPFLTR_INFO_LEVEL,"Driver Loaded\n");

    return STATUS_SUCCESS;

}
//
// PRE OPERATION
//
OB_PREOP_CALLBACK_STATUS ObjectPreCallback(
  IN  PVOID RegistrationContext,
  IN  POB_PRE_OPERATION_INFORMATION OperationInformation
)
{
    LPSTR ProcName;
    // OB_PRE_OPERATION_INFORMATION OpInfo;



UNREFERENCED_PARAMETER(RegistrationContext);


ProcName=GetProcessNameFromPid(PsGetProcessId((PEPROCESS)OperationInformation->Object));

if( !_stricmp(ProcName,"calc.exe") )
{
    if (OperationInformation->Operation == OB_OPERATION_HANDLE_CREATE)
     {
       if ((OperationInformation->Parameters->CreateHandleInformation.OriginalDesiredAccess & PROCESS_TERMINATE) == PROCESS_TERMINATE)
         {
           OperationInformation->Parameters->CreateHandleInformation.DesiredAccess &= ~PROCESS_TERMINATE;
         }
       if ((OperationInformation->Parameters->CreateHandleInformation.OriginalDesiredAccess & PROCESS_VM_OPERATION) == PROCESS_VM_OPERATION)
        {
          OperationInformation->Parameters->CreateHandleInformation.DesiredAccess &= ~PROCESS_VM_OPERATION;
        }
       if ((OperationInformation->Parameters->CreateHandleInformation.OriginalDesiredAccess & ~PROCESS_VM_READ) == PROCESS_VM_READ)
        {
         OperationInformation->Parameters->CreateHandleInformation.DesiredAccess &= ~PROCESS_VM_READ;
        }
      if ((OperationInformation->Parameters->CreateHandleInformation.OriginalDesiredAccess & PROCESS_VM_WRITE) == PROCESS_VM_WRITE)
        {
         OperationInformation->Parameters->CreateHandleInformation.DesiredAccess &= ~PROCESS_VM_WRITE;
        }
     }
}
    DbgPrintEx( DPFLTR_IHVDRIVER_ID,  DPFLTR_INFO_LEVEL,"ObjectPreCallback ----> Process Name [%s] \n", ProcName);
   return OB_PREOP_SUCCESS;
}
//
//POST OPERATION
//

VOID ObjectPostCallback(
  IN  PVOID RegistrationContext,
  IN  POB_POST_OPERATION_INFORMATION OperationInformation
)
{
   DbgPrintEx( DPFLTR_IHVDRIVER_ID,  DPFLTR_INFO_LEVEL,"PostProcCreateRoutine. \n");
}
//
// REGISTE CALLBACK FUNCTION
//

NTSTATUS RegisterCallbackFunction()
{
    NTSTATUS ntStatus = STATUS_SUCCESS;
    UNICODE_STRING Altitude;
    USHORT filterVersion = ObGetFilterVersion();
    USHORT registrationCount = 1;
    OB_OPERATION_REGISTRATION RegisterOperation;
    OB_CALLBACK_REGISTRATION RegisterCallBack;
    REG_CONTEXT RegistrationContext;
    memset(&RegisterOperation, 0, sizeof(OB_OPERATION_REGISTRATION));
    memset(&RegisterCallBack, 0, sizeof(OB_CALLBACK_REGISTRATION));
    memset(&RegistrationContext, 0, sizeof(REG_CONTEXT));
    RegistrationContext.ulIndex = 1;
    RegistrationContext.Version = 120;
    if (filterVersion == OB_FLT_REGISTRATION_VERSION) {
        DbgPrintEx( DPFLTR_IHVDRIVER_ID,  DPFLTR_INFO_LEVEL,"Filter Version is correct.\n");

        RegisterOperation.ObjectType = PsProcessType;
        RegisterOperation.Operations = OB_OPERATION_HANDLE_CREATE;
        RegisterOperation.PreOperation = ObjectPreCallback;
        RegisterOperation.PostOperation = ObjectPostCallback;
        RegisterCallBack.Version = OB_FLT_REGISTRATION_VERSION;
        RegisterCallBack.OperationRegistrationCount = registrationCount;
        RtlInitUnicodeString(&Altitude, L"XXXXXXX");
        RegisterCallBack.Altitude = Altitude;
        RegisterCallBack.RegistrationContext = &RegistrationContext;
        RegisterCallBack.OperationRegistration = &RegisterOperation;
        DbgPrintEx( DPFLTR_IHVDRIVER_ID,  DPFLTR_INFO_LEVEL,"Register Callback Function Entry.\n");


        ntStatus = ObRegisterCallbacks(&RegisterCallBack, &_CallBacks_Handle);
        if (ntStatus == STATUS_SUCCESS) {
        DbgPrintEx( DPFLTR_IHVDRIVER_ID,  DPFLTR_INFO_LEVEL,"Register Callback Function Successful.\n");
        }
        else {
            if (ntStatus == STATUS_FLT_INSTANCE_ALTITUDE_COLLISION) {
                DbgPrintEx( DPFLTR_IHVDRIVER_ID,  DPFLTR_ERROR_LEVEL,"Status Filter Instance Altitude Collision.\n");
            }
            if (ntStatus == STATUS_INVALID_PARAMETER) {
               DbgPrintEx( DPFLTR_IHVDRIVER_ID,  DPFLTR_ERROR_LEVEL,"Status Invalid Parameter.\n");
            }
            if (ntStatus == STATUS_ACCESS_DENIED) {
                DbgPrintEx( DPFLTR_IHVDRIVER_ID,  DPFLTR_ERROR_LEVEL,"The callback routines do not reside in a signed kernel binary image.\n");
            }
            if (ntStatus == STATUS_INSUFFICIENT_RESOURCES) {
               DbgPrintEx( DPFLTR_IHVDRIVER_ID,  DPFLTR_ERROR_LEVEL,"Status Allocate Memory Failed.\n");
            }
              DbgPrintEx( DPFLTR_IHVDRIVER_ID,  DPFLTR_ERROR_LEVEL,"Register Callback Function Failed with 0x%08x\n",ntStatus);
        }
    }
    else {
               DbgPrintEx( DPFLTR_IHVDRIVER_ID,  DPFLTR_ERROR_LEVEL,"Filter Version is not supported.\n");
    }
    return ntStatus;
}
//
// FREE PROC FILTER
//

NTSTATUS FreeProcFilter()
{
    // if the callbacks are active - remove them
    if (NULL != _CallBacks_Handle)
    {
        ObUnRegisterCallbacks(_CallBacks_Handle);
        _CallBacks_Handle=NULL;
    }
    return STATUS_SUCCESS;
}


LPSTR GetProcessNameFromPid(HANDLE pid)
{
    PEPROCESS Process;
    if (PsLookupProcessByProcessId(pid, & Process) == STATUS_INVALID_PARAMETER)
    {
        return "pid???";
    }
    return (LPSTR)PsGetProcessImageFileName(Process);

}

common.h

#include <ntddk.h>

// coded by Behrooz

//-----------------------------------------------
//  Defines
//-----------------------------------------------

//Process Security and Access Rights
#define PROCESS_CREATE_THREAD  (0x0002)
#define PROCESS_CREATE_PROCESS (0x0080)
#define PROCESS_TERMINATE      (0x0001)
#define PROCESS_VM_WRITE       (0x0020)
#define PROCESS_VM_READ        (0x0010)
#define PROCESS_VM_OPERATION   (0x0008)
#define PROCESS_SUSPEND_RESUME (0x0800)


#define MAXIMUM_FILENAME_LENGTH 256
//-----------------------------------------------
// callback
//-----------------------------------------------

PVOID _CallBacks_Handle = NULL;

typedef struct _OB_REG_CONTEXT {
    __in USHORT Version;
    __in UNICODE_STRING Altitude;
    __in USHORT ulIndex;
    OB_OPERATION_REGISTRATION *OperationRegistration;
} REG_CONTEXT, *PREG_CONTEXT;


//-----------------------------------------------
// PID2ProcName
//-----------------------------------------------
extern UCHAR *PsGetProcessImageFileName(IN PEPROCESS Process);

extern   NTSTATUS PsLookupProcessByProcessId(
     HANDLE ProcessId,
    PEPROCESS *Process
);
typedef PCHAR (*GET_PROCESS_IMAGE_NAME) (PEPROCESS Process);
GET_PROCESS_IMAGE_NAME gGetProcessImageFileName;

LPSTR GetProcessNameFromPid(HANDLE pid);



//-----------------------------------------------
//  Forward Declaration
//-----------------------------------------------
NTSTATUS DriverEntry(
    IN PDRIVER_OBJECT DriverObject, 
    IN PUNICODE_STRING RegistryPath
    );

VOID UnloadDriver(
    IN PDRIVER_OBJECT DriverObject
    );

OB_PREOP_CALLBACK_STATUS ObjectPreCallback(
  IN  PVOID RegistrationContext,
  IN  POB_PRE_OPERATION_INFORMATION OperationInformation
  );

VOID ObjectPostCallback(
  IN  PVOID RegistrationContext,
  IN  POB_POST_OPERATION_INFORMATION OperationInformation
  );

NTSTATUS RegisterCallbackFunction() ;
NTSTATUS FreeProcFilter();

我的测试结果: enter image description here

关于64-bit - 在 x64 驱动程序中 Hook ZwTerminateProcess(不带 SSDT),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20552300/

相关文章:

c++ - 如何强制调用类的全局实例的析构函数和构造函数(所以 "re-init"是类实例)

windows-7 - 简单问题: Can x86 apps take advantage of the extra RAM a x64 OS gives?

c++ - 计算(64 位无符号整数)*(64 位无符号整数)除以 2^64 的商

.net - 64 位模式下的经典 ASP 和 .NET COM DLL 注册问题

node.js - 根据事务 Sequelize hook

python - 在 mongodb 上进行服务器端 Hook 的建议方法是什么?

c - 从驱动程序写入事件日志

internet-explorer - 等待间歇性故障

php - 如何在WordPress中设置动态 `home`和 `siteurl`?

c - 获取簇大小