概述: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;
}