周壑x64位内核学习 (七)、PatchGuard 1

PatchGuard补丁保护

一、什么是PG

PatchGuard就是Windows Vista(以上)的内核保护系统,防止任何非授权软件试图“修改”Windows内核。它会循环检查几个敏感驱动是否被修改,如果发现,则引发0x109蓝屏
 
0
 
 
 

 

 InitKDBG节保存了PG保护的主要检测的逻辑

 
0
 
 

二、win10进程断链验证PG的存在

 
上面文档说到,PG保护不允许断链,否则会蓝屏,我们来验证一下PG保护的存在
 

1、代码

三环代码:
// 加载驱动.cpp : Defines the entry point for the console application. // //编译器: vc6++// #include "stdafx.h" #include <windows.h> #include <winioctl.h> //不加这个头文件,消息码会报错// #define DRIVER_NAME L"Kill_Eprocess_chain" //这个取驱动名// #define DRIVER_PATH L"Kill_Eprocess_chain.sys" #define DRIVER_LINK L"\\\\.\\MyTestDriver" //这个名字随便起// #define OPERFIR_EPROCESS_CHAIN CTL_CODE(FILE_DEVICE_UNKNOWN,0x900,METHOD_BUFFERED,FILE_ANY_ACCESS) void LoadDriver() { //获取驱动完整路径// WCHAR szDriverFullPath[MAX_PATH] = {0}; GetFullPathNameW(DRIVER_PATH,MAX_PATH,szDriverFullPath,NULL); //今天又测了测这个函数,中文路径下行不通,而且,定位的路径依赖于此exe文件的路径// //打开服务管理器// SC_HANDLE hServiceMgr = NULL; // SCM管理器句柄 hServiceMgr = OpenSCManagerW(NULL,NULL,SC_MANAGER_ALL_ACCESS); if(!hServiceMgr){ printf("OpenSCManagerW fail ,wrong code is %d \n",GetLastError()); } //创建驱动服务// SC_HANDLE hServiceDDK = NULL; hServiceDDK = CreateServiceW( hServiceMgr, DRIVER_NAME, DRIVER_NAME, SERVICE_ALL_ACCESS, SERVICE_KERNEL_DRIVER, SERVICE_DEMAND_START, SERVICE_ERROR_IGNORE, szDriverFullPath, NULL, NULL, NULL, NULL, NULL); if(hServiceDDK == NULL) { printf("CreateServiceW failed ,error code is %d\n",GetLastError()); return ; } hServiceDDK = OpenServiceW(hServiceMgr, DRIVER_NAME, SERVICE_ALL_ACCESS); if(!StartService(hServiceDDK, NULL, NULL)) { printf("StartService failed , error code is %d \n",GetLastError()); return ; } CloseServiceHandle(hServiceDDK); CloseServiceHandle(hServiceMgr); } void UnloadDriver() { SC_HANDLE hServiceMgr = OpenSCManagerW(0, 0, SC_MANAGER_ALL_ACCESS); SC_HANDLE hServiceDDK = OpenServiceW(hServiceMgr, DRIVER_NAME, SERVICE_ALL_ACCESS); SERVICE_STATUS SvrStatus; ControlService(hServiceDDK, SERVICE_CONTROL_STOP, &SvrStatus); //向服务器发送控制代码//通知服务应该停止// DeleteService(hServiceDDK); CloseServiceHandle(hServiceDDK); CloseServiceHandle(hServiceMgr); } void R0ToR3(DWORD pid) { HANDLE hDevice = CreateFileW(DRIVER_LINK, GENERIC_WRITE | GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if(INVALID_HANDLE_VALUE == hDevice) { printf("CreateFile filed,error code is %d\n",GetLastError()); return ; } int ret = DeviceIoControl(hDevice, OPERFIR_EPROCESS_CHAIN, &pid, 4, NULL, 0, NULL, NULL); if(ret == 0) { printf("DeviceIoControl filed , error code is %d\n",GetLastError()); } CloseHandle(hDevice); } int main(int argc, char* argv[]) { DWORD PID; printf("请输入PID的值:\n"); scanf("%d",&PID); LoadDriver(); R0ToR3(PID);//03环通信// UnloadDriver(); // 作用是标记驱动要被卸载// getchar(); return 0; }

驱动代码:

/****************************/ /* */ /*编译器: VS2019 */ /*编译者: _TLSN */ /*编译日期 :2022/3/26 上午 */ /* */ /****************************/ #include <ntifs.h> #include <ntddk.h> #define DEVICE_NAME L"\\Device\\MyDevice" //#define DRIVER_LINK L"\\\\.\\MyTestDriver" //这个名字与0环一致// #define SYMBOLICTINK_NAME L"\\??\\MyTestDriver" //与三环一致// #define OPERFIR_EPROCESS_CHAIN CTL_CODE(FILE_DEVICE_UNKNOWN,0x900,METHOD_BUFFERED,FILE_ANY_ACCESS) VOID DriverUnload(PDRIVER_OBJECT driver); void HideEProcessChain(ULONG32 PID); NTSTATUS IrpDeviceControlProc(PDEVICE_OBJECT pObject, PIRP pIrp); NTSTATUS IrpCreateProc(PDEVICE_OBJECT pObject, PIRP pIrp); NTSTATUS IrpCloseProc(PDEVICE_OBJECT pObject, PIRP pIrp); NTSTATUS DriverEntry(PDRIVER_OBJECT driver, PUNICODE_STRING pRegPath) { NTSTATUS status; PDEVICE_OBJECT DeviceObject; UNICODE_STRING DeviceName; UNICODE_STRING SymbolicLinkName; RtlInitUnicodeString(&DeviceName, DEVICE_NAME); status = IoCreateDevice(driver, 0, &DeviceName, FILE_DEVICE_UNKNOWN, FILE_DEVICE_SECURE_OPEN, FILE_DEVICE_SECURE_OPEN, &DeviceObject); if (status != STATUS_SUCCESS) { DbgPrint("IoCreateDevice failed!status is %d\r\n", status); return status; } //设置数据交互方式/ DeviceObject->Flags = DO_BUFFERED_IO; RtlInitUnicodeString(&SymbolicLinkName, SYMBOLICTINK_NAME); //创建符号链接 status = IoCreateSymbolicLink(&SymbolicLinkName, &DeviceName); if (status != STATUS_SUCCESS) { DbgPrint("IoCreateSymbolicLink error status is %d!\r\n",status); IoDeleteDevice(DeviceObject); return status; } //设置派遣函数// driver->MajorFunction[IRP_MJ_CREATE] = IrpCreateProc; driver->MajorFunction[IRP_MJ_CLOSE] = IrpCloseProc; driver->MajorFunction[IRP_MJ_DEVICE_CONTROL] = IrpDeviceControlProc; driver->DriverUnload = DriverUnload; DbgPrint("Driver load ok!\n"); return STATUS_SUCCESS; } VOID DriverUnload(PDRIVER_OBJECT driver) { UNICODE_STRING LinkName ; RtlInitUnicodeString(&LinkName, SYMBOLICTINK_NAME); IoDeleteSymbolicLink(&LinkName); IoDeleteDevice(driver->DeviceObject); DbgPrint("Driver unloaded\n"); } NTSTATUS IrpDeviceControlProc(PDEVICE_OBJECT pObject, PIRP pIrp) { NTSTATUS status = STATUS_INVALID_DEVICE_REQUEST; PIO_STACK_LOCATION pIrpStack; ULONG uIoControlCode; PVOID pIoBuffer; ULONG uInLength; ULONG uOutLength; UCHAR uRead[0x10] = { 0 }; ULONG dwRead; //获取IRP的数据// pIrpStack = IoGetCurrentIrpStackLocation(pIrp); //获取控制码// uIoControlCode = pIrpStack->Parameters.DeviceIoControl.IoControlCode; //获取缓冲区地址// pIoBuffer = pIrp->AssociatedIrp.SystemBuffer;//输入和输出缓冲区都是一个// //Ring3 发送数据的长度// uInLength = pIrpStack->Parameters.DeviceIoControl.InputBufferLength; //Ring0 发送数据的长度// uOutLength = pIrpStack->Parameters.DeviceIoControl.OutputBufferLength; switch (uIoControlCode) { case OPERFIR_EPROCESS_CHAIN: { if (uInLength != 4) { DbgPrint("Invalid PID\n"); break; } UINT32 pid; // 读取缓冲区 memcpy(&pid, pIoBuffer, uInLength); DbgPrint("Hide %d PID\n", pid); HideEProcessChain(pid); break; } default: DbgPrint("nothing code\r\n"); } // 返回状态如果不设置,Ring3返回值报错 pIrp->IoStatus.Status = STATUS_SUCCESS; IoCompleteRequest(pIrp, IO_NO_INCREMENT); return STATUS_SUCCESS; } void HideEProcessChain(ULONG32 PID) { PEPROCESS pEprocess = NULL; pEprocess = PsGetCurrentProcess(); //获取当前线程的进程ID// PLIST_ENTRY pActiveProcessLinks = (LIST_ENTRY*)((ULONG64)pEprocess + 0x2f0); PLIST_ENTRY pNextLinks = pActiveProcessLinks->Flink;//flink 后一个// ULONG32 uPeocessPID = 0; while (pNextLinks != pActiveProcessLinks) { uPeocessPID = *(PULONG64)((ULONG64)pNextLinks - 0x2f0 + 0x2e8); //0x2e8 :UniqueProcessId // if (uPeocessPID == (ULONG64)PID) { pNextLinks->Flink->Blink = pNextLinks->Blink; pNextLinks->Blink->Flink = pNextLinks->Flink; DbgPrint("HideProcess Success\n"); DbgPrint("wait PG protect\n"); } pNextLinks = pNextLinks->Flink; } } NTSTATUS IrpCreateProc(PDEVICE_OBJECT pObject, PIRP pIrp) { DbgPrint("connect success\n"); //设置返回状态// pIrp->IoStatus.Status = STATUS_SUCCESS; pIrp->IoStatus.Information = 0; IoCompleteRequest(pIrp, IO_NO_INCREMENT);//为什么要设置成IO_NO_INCREMENT?// return STATUS_SUCCESS; } NTSTATUS IrpCloseProc(PDEVICE_OBJECT pObject, PIRP pIrp) { DbgPrint("unconnect success\n"); //设置返回状态// pIrp->IoStatus.Status = STATUS_SUCCESS; pIrp->IoStatus.Information = 0; IoCompleteRequest(pIrp, IO_NO_INCREMENT);//为什么要设置成IO_NO_INCREMENT?// return STATUS_SUCCESS; }

2、验证

这里有一个PID为5016的记事本进程
0
 
运行驱动加载程序,输入PID 5016
0
0
断链成功
在任务管理器上已找不到记事本进程
 
0
 
过了一小会儿,windbg上出现中断,开始蓝屏
 
0
 
可以看到,断链后,操作系统并没有马上蓝屏,而是过了一会儿才开始蓝屏的,这应该就是PG保护的检测机制造成的
 

__EOF__

本文作者_TLSN
本文链接https://www.cnblogs.com/lordtianqiyi/articles/16061272.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   TLSN  阅读(822)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 25岁的心里话
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示