我发现并阅读了这个问题,但我没有找到答案SSDT hooking alternative in x64 systems
我想保护我的申请免受其他程序的终止。在32位版本的Windows中,我使用SSDT hooking
来挂钩ZwTerminateProcess
或ZwOpenProcess
。我现在要将程序升级为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
)并将其替换为SSDT中的原始ZwOpenProcess
,但在x64窗口中我不知道该怎么做:(:
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);
}
任何想法??
(对不起,如果我的英语不好)
答案 0 :(得分: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();
我测试的结果:
答案 1 :(得分:2)
感谢您的代码,我在win10 x64上成功测试了它。 顺便说一下,我发现ObRegisterCallbacks返回STATUS_ACCESS_DENIED即使我已经签署了我的驱动程序。 所以我问了很多人,然后我找到了解决方案。 将此文本附加到您&#34; source&#34;文件: LINKER_FLAGS = / integritycheck
然后您可以重建并重新启动您的驱动程序。它发现于bbs.pediy.com
答案 2 :(得分:1)
看起来不需要 .inf 文件。只是 SC CREATE ServiceName type= kernel binPath= pathtoyourfile。
答案 3 :(得分:-1)
有人可以做“ObUnregisterCallbacks”甚至注册他们自己以防止你检测它。