SSDT Hook (HookZwTerminateProcess)—— 实现任务管理器无法关闭进程

本节的目的是通过驱动程序修改 ntoskrnl.exe 程序的 SSDT 表中的函数地址表,以实现 SSDT Hook 。本次的测试函数为 R3 API 函数 ZwTerminateProcess ,通过 Hook 该函数,以实现任务管理器无法强制关闭进程,只有通过进程的关闭方法才可以正常结束进程。


Hook 该函数的关键是判断 ZwTerminateProcess 函数中的进程句柄 hProcess 。当进程是通过自身的关闭方法关闭的话,该句柄的值应为 0xffffffff0x00 ,而通过其他进程调用 ZwTerminateProcess 函数关闭的话,该句柄的值不为以上情况。因此,我们可以通过这种方法来判断,进程是主动关闭的,还是被动关闭的。

测试代码如下:

#include <ntddk.h>
#include <ntstatus.h>

/************************************************************************/
/* 类型声明                                                             */
/************************************************************************/

// 系统服务表
typedef struct _KSYSTEM_SERVICE_TABLE
{
    
    
	PULONG ServiceTableBase;			// 函数地址表
	PULONG ServiceCounterTableBase;		// SSDT 函数被调用的次数
	ULONG NumberOfService;				// 函数个数
	PULONG ParamTableBase;				// 函数参数表
} KSYSTEM_SERVICE_TABLE, * PKSYSTEM_SERVICE_TABLE;

typedef struct _KSERVICE_TABLE_DESCRIPTOR
{
    
    
	KSYSTEM_SERVICE_TABLE ntoskrnl;		// ntoskrnl.exe 函数
	KSYSTEM_SERVICE_TABLE win32k;		// win32k.sys 函数
	KSYSTEM_SERVICE_TABLE unUsed1;
	KSYSTEM_SERVICE_TABLE unUsed2;
} KSERVICE_TABLE_DESCRIPTOR, * PKSERVICE_TABLE_DESCRIPTOR;

// NTOPENPROCESS
typedef NTSTATUS(*NTOPENPROCESS) (HANDLE hProcess, UINT32 uExitCode);


/************************************************************************/
/* 函数声明                                                             */
/************************************************************************/

VOID DriverUnload(PDRIVER_OBJECT pDriver);
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriver, PUNICODE_STRING reg_path);
VOID PageProtectOff();
VOID PageProtectOn();
VOID HookZwTerminateProcess();
VOID UnHookZwTerminateProcess();
NTSTATUS MyHookZwTerminateProcess(HANDLE hProcess, UINT32 uExitCode);


/************************************************************************/
/* 全局变量                                                             */
/************************************************************************/

extern PKSERVICE_TABLE_DESCRIPTOR KeServiceDescriptorTable; // ntoskrnl.exe 导出的全局变量
ULONG uOldZwTerminateProcess; // 旧的函数地址


/************************************************************************/
/* 函数定义                                                             */
/************************************************************************/

// 驱动入口
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriver, PUNICODE_STRING reg_path)
{
    
    
	// HOOK
	HookZwTerminateProcess();

	pDriver->DriverUnload = DriverUnload;

	return STATUS_SUCCESS;
}

// 卸载驱动
VOID DriverUnload(PDRIVER_OBJECT pDriver)
{
    
    
	UnHookZwTerminateProcess();
	DbgPrint("Driver unloaded.\n");
}

// 关闭页保护
VOID PageProtectOff()
{
    
    
	__asm
	{
    
    
		cli; // 关闭中断
		mov eax, cr0;
		and eax, not 0x10000; // WP位置0
		mov cr0, eax;
	}
}

// 开启页保护
VOID PageProtectOn()
{
    
    
	__asm
	{
    
    
		mov eax, cr0;
		or eax, 0x10000; // WP位置1
		mov cr0, eax;
		sti; // 恢复中断
	}
}

// HOOK NtOpenProcess
VOID HookZwTerminateProcess()
{
    
    
	PageProtectOff();
	uOldZwTerminateProcess = KeServiceDescriptorTable->ntoskrnl.ServiceTableBase[0x101];
	KeServiceDescriptorTable->ntoskrnl.ServiceTableBase[0x101] = (ULONG)MyHookZwTerminateProcess;
	PageProtectOn();
}

// UnHOOK NtOpenProcess
VOID UnHookZwTerminateProcess()
{
    
    
	PageProtectOff();
	KeServiceDescriptorTable->ntoskrnl.ServiceTableBase[0x101] = uOldZwTerminateProcess;
	PageProtectOn();
}

// 被修改的 NtOpenProcess 函数,简单打印参数
NTSTATUS MyHookZwTerminateProcess(HANDLE hProcess, UINT32 uExitCode)
{
    
    
	DbgPrint("进程句柄:%x  退出码:%x\n", hProcess, uExitCode);
	if (!(hProcess == 0xffffffff || hProcess == 0))
	{
    
    
		DbgPrint("拒绝关闭请求!\n");
		return 0;
	}
	else
		return ((NTOPENPROCESS)uOldZwTerminateProcess)(hProcess, uExitCode);
}

效果图如下:

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_43890959/article/details/114441504