概述:windows 驱动实现对进程的保护

0x01 说明

主要的逻辑是在驱动中 Hook NtTerminateProcess 函数

#include <Ntifs.h>
 
 
//0x7A NTOpenProcess
//0x101 NtTerminateProcess
#define FuctionID 0x101	//调用号
 
void PageProtectOn()
{
	//恢复内存保护
	__asm
	{
		mov eax,cr0
			or eax,10000h
			mov cr0,eax
			sti
	}
}
 
void PageProtectOff()
{
	//去掉内存保护
	__asm
	{
		cli
			mov eax,cr0
			and eax,not 10000h
			mov cr0,eax		
	}
}
 
//1、找到系统服务表:函数地址表
typedef struct _KSYSTEM_SERVICE_TABLE
{
	PULONG ServiceTableBase;			//函数地址表基地址
	PULONG ServiceCounterTableBase; //被访问了多少次
	ULONG  NumberOfService;			//表中服务函数的总数
	PUCHAR ParamTableBase;			//服务函数的参数个数数组的起始地址
}KSYSTEM_SERVICE_TABLE,*PKSYSTEM_SERVICE_TABLE;
 
typedef struct _KSERVICE_DESCRIPTOR_TABLE
{
	KSYSTEM_SERVICE_TABLE ntoskrnl;//ntoskrnl.exe的函数
	KSYSTEM_SERVICE_TABLE win32k;//win32k.sys的函数
	KSYSTEM_SERVICE_TABLE notUsed1;//
	KSYSTEM_SERVICE_TABLE notUsed2;//
}KSERVICE_DESCRIPTOR_TABLE,*PKSERVICE_DESCRIPTOR_TABLE;
 
//NtTerminateProcess函数指针
typedef NTSTATUS (*NTTERMINATEPROCESS) (HANDLE ProcessHandle, NTSTATUS ExitStatus);
 
 
//KeServiceDescriptorTable时ntoskrnl.exe所导出的全局变量 申明一下就可以直接用了
extern PKSERVICE_DESCRIPTOR_TABLE KeServiceDescriptorTable; 
//存储原来的函数地址
ULONG uOldNtTerminateProcess;
 
//2.准备用于替换的函数
NTSTATUS MyNtTerminateProcess(HANDLE ProcessHandle, NTSTATUS ExitStatus)
{
	//自己的业务..各种过滤 或者修改返回结果
	PEPROCESS pEprocess;
	NTSTATUS status;
	PCHAR ImageFileName;
	
 
	//通过句柄获取EPROCESS
	status = ObReferenceObjectByHandle(ProcessHandle,FILE_ANY_ACCESS,*PsProcessType,KernelMode,&pEprocess,NULL);
	if (!NT_SUCCESS(status))
	{
		return status;
	}
	//获取进程名字 _EPROCESS + 0x171  == ImageFileName
	ImageFileName = (PCHAR)pEprocess + 0x174;
	//判断是否是要保护的进程
	if (strcmp(ImageFileName, "notepad.exe") == 0)
	{
		//判断如何退出
		if (ProcessHandle == (HANDLE)0xFFFFFFFF)
		{
			//点X关闭
			DbgPrint("点X关闭 成功退出:%s: NtTerminateProcess(%x, %x)\n", ImageFileName, ProcessHandle, ExitStatus);
			return ((NTTERMINATEPROCESS)uOldNtTerminateProcess)(ProcessHandle, ExitStatus);
		}
		else if(ExitStatus == 1)
		{
			// 通过任务管理器关闭
			DbgPrint("通过任务管理器关闭 拒绝关闭:%s: NtTerminateProcess(%x, %x)\n", ImageFileName, ProcessHandle, ExitStatus);
			return STATUS_ACCESS_DENIED;
		}
		else
		{
			return STATUS_ACCESS_DENIED;
		}
	}
 
	return ((NTTERMINATEPROCESS)uOldNtTerminateProcess)(ProcessHandle, ExitStatus);
}
//3.修改函数地址
NTSTATUS HookNtTerminateProcess()
{
	NTSTATUS Status;
	Status = STATUS_SUCCESS;
	PageProtectOff();
	uOldNtTerminateProcess = KeServiceDescriptorTable->ntoskrnl.ServiceTableBase[FuctionID];
	KeServiceDescriptorTable->ntoskrnl.ServiceTableBase[FuctionID] = (ULONG)MyNtTerminateProcess;
	PageProtectOn();
	return Status;
}
//4.恢复
VOID UnHookNtTerminateProcess()
{
	PageProtectOff();
	KeServiceDescriptorTable->ntoskrnl.ServiceTableBase[FuctionID] = (ULONG)uOldNtTerminateProcess;
	PageProtectOn();
}
//卸载函数
VOID DriverUnload(PDRIVER_OBJECT driver)
{
	UnHookNtTerminateProcess();
	KdPrint(("驱动程序停止运行了.\r\n"));
}
 
//入口函数,相当于main
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriver, PUNICODE_STRING reg_path)
{
	HookNtTerminateProcess();
 
	//注册销毁回调函数
	pDriver->DriverUnload = DriverUnload;
	return STATUS_SUCCESS;
}