2013-12-12 186 views
5

我发现阅读这个问题,但我没有发现我的答案SSDT hooking alternative in x64 systems钩ZwTerminateProcess(无SSDT)

我想其他的方案,以保护我的对终端的应用程序。在32Bit版本的Windows中,我使用SSDT hooking来挂钩ZwTerminateProcessZwOpenProcess。我必须将我的程序升级到64位版本的Windows。 不幸的是,在64位窗口中,我们不能使用SSDT钩子(Because Patch Guard (KPP)),请注意,在这种情况下,我不想绕过PG,并且只使用内核模式挂钩。例如我不想我的计划开始终止(即使)由下面的代码:

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)和原ZwOpenProcess在SSDT但在64位取代它窗户我不知道我该怎么办:(:

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

任何想法?

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

+1

这就是为什么我们喜欢Patch Guard。 –

+0

@HansPassant :),是的,我们爱PG,但我正在开发安全软件,对我来说保护我的程序很重要。 – Behrooz

+0

微软开发了PG,所以你不再需要这些骇人的黑客。 –

回答

11

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

#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

+0

感谢分享,告诉我,您正在使用的是什么版本的WDK? – navossoc

+1

@navossoc欢迎你,WINDDK ver 7600.16385.1 – Behrooz

+0

我已经试过这段代码,但是'ObRegisterCallbacks'返回'STATUS_ACCESS_DENIED',即使我签了我的驱动程序。请帮助我, –

-1

有人能做到 “ObUnregisterCallbacks”,甚至注册自己,以防止你检测它。

2

感谢您的代码,我测试了win10 x64的成功。 顺便说一句,我发现ObRegisterCallbacks返回STATUS_ACCESS_DENIED,即使我已经签署了我的驱动程序。 所以我问很多人,然后我找到了解决办法。 在您的“源”文件中追加此文本: LINKER_FLAGS =/integritycheck

然后您可以重建并重新安排驱动程序。它被发现在bbs.pediy.com