32位/64位WINDOWS驱动之进程保护参考地址:
参考https://blog.csdn.net/cosmoslife/article/details/113995641
OpenProcess()函数
方法名称:OpenProcess
位置:Kernel32.dll
OpenProcess 函数用来打开一个已存在的进程对象,并返回进程的句柄。
1.函数原型
HANDLE OpenProcess(
DWORD dwDesiredAccess,
BOOL bInheritHandle,
DWORD dwProcessId
);
参数
#define PROCESS_TERMINATE (0x0001) //终止一个进程的权限,使用TerminateProcess
#define PROCESS_CREATE_THREAD (0x0002) //需要创建一个线程
#define PROCESS_SET_SESSIONID (0x0004)
#define PROCESS_VM_OPERATION (0x0008)//操作进程内存空间的权限(可用VirtualProtectEx和WriteProcessMemory)
#define PROCESS_VM_READ (0x0010)//读取进程内存空间的权限,可使用ReadProcessMemory
#define PROCESS_VM_WRITE (0x0020)//读取进程内存空间的权限,可使用WriteProcessMemory
#define PROCESS_DUP_HANDLE (0x0040)//重复使用DuplicateHandle句柄
#define PROCESS_CREATE_PROCESS (0x0080)//需要创建一个进程
#define PROCESS_SET_QUOTA (0x0100)//设置内存限制的权限,使用SetProcessWorkingSetSize
#define PROCESS_SET_INFORMATION (0x0200)//设置某些信息的权限,如进程优先级
#define PROCESS_QUERY_INFORMATION (0x0400)//获得进程信息的权限,如它的退出代码、优先级
#define PROCESS_SUSPEND_RESUME (0x0800)//暂停或恢复进程的权限
#define PROCESS_QUERY_LIMITED_INFORMATION (0x1000)/获得某些信息的权限,如果获得了PROCESS_QUERY_INFORMATION,也拥有PROCESS_QUERY_LIMITED_INFORMATION权限/
#define PROCESS_SET_LIMITED_INFORMATION (0x2000)
void 安装内存保护();
void 卸载内存保护();
在驱动层添加个文件进程保护,在这个文件里面添加一个驱动保护.c 驱动保护.h
1.驱动保护.c代码如下
#include <ntifs.h>
#include "进程保护.h"
OB_PREOP_CALLBACK_STATUS
my_pre_callback(
PVOID RegistrationContext,
POB_PRE_OPERATION_INFORMATION OperationInformation
)
{
RegistrationContext;
DbgPrint("yjx:sys pEPROCESS=%p", OperationInformation->Object);
if (OperationInformation->KernelHandle)
{
//内核创建
}
else
{
//用户层
ACCESS_MASK old权限 = OperationInformation->Parameters->CreateHandleInformation.OriginalDesiredAccess;
//ACCESS_MASK oldl = old权限;
ACCESS_MASK new1 = OperationInformation->Parameters->CreateHandleInformation.DesiredAccess;
//排除PROCESS_VM_READ权限
old权限 &= ~PROCESS_TERMINATE;//阻止结束进程 拦截结束进程
//排除掉PROCESS_VM_WRITE
/*old权限 &= ~PROCESS_VM_WRITE;*/
//返回我们修改过的权限 OpenProcess
OperationInformation->Parameters->CreateHandleInformation.DesiredAccess = old权限;
DbgPrint("yjx:old权限=%x 新权限 = %X",old权限,new1);
}
return OB_PREOP_SUCCESS;
}
HANDLE gs_HandleCallback = NULL;//用来存放返回的句柄 以方便卸载对应功能
void 安装内存保护()
{
OB_CALLBACK_REGISTRATION ob1_callback_reg = { 0 };
OB_OPERATION_REGISTRATION ob2_operation = { 0 };
//ob1 5项
RtlInitUnicodeString(&ob1_callback_reg.Altitude,L"321000");
ob1_callback_reg.RegistrationContext = NULL;
ob1_callback_reg.Version = OB_FLT_REGISTRATION_VERSION;//ObGetFilterVersion();
ob1_callback_reg.OperationRegistrationCount = 1;//只注册了一个回调pre
ob1_callback_reg.OperationRegistration = &ob2_operation;
//接下来初始化 ob2_operation
ob2_operation.ObjectType = PsProcessType;
ob2_operation.Operations = OB_OPERATION_HANDLE_CREATE;
ob2_operation.PostOperation = NULL;
ob2_operation.PreOperation = my_pre_callback;
ObRegisterCallbacks(&ob1_callback_reg, &gs_HandleCallback);//INTEGRITYCHECK
DbgPrint("yjx:sys 安装内存保护 gs_HandleCallback=%p", gs_HandleCallback);
}
void 卸载内存保护()
{
if(gs_HandleCallback) ObUnRegisterCallbacks(gs_HandleCallback);
DbgPrint("yjx:sys 卸载内存保护");
}
2.驱动保护.h 代码如下:
#pragma once
#define PROCESS_TERMINATE (0x0001) //终止一个进程的权限,使用TerminateProcess
#define PROCESS_CREATE_THREAD (0x0002) //需要创建一个线程
#define PROCESS_SET_SESSIONID (0x0004)
#define PROCESS_VM_OPERATION (0x0008)//操作进程内存空间的权限(可用VirtualProtectEx和WriteProcessMemory)
#define PROCESS_VM_READ (0x0010)//读取进程内存空间的权限,可使用ReadProcessMemory
#define PROCESS_VM_WRITE (0x0020)//读取进程内存空间的权限,可使用WriteProcessMemory
#define PROCESS_DUP_HANDLE (0x0040)//重复使用DuplicateHandle句柄
#define PROCESS_CREATE_PROCESS (0x0080)//需要创建一个进程
#define PROCESS_SET_QUOTA (0x0100)//设置内存限制的权限,使用SetProcessWorkingSetSize
#define PROCESS_SET_INFORMATION (0x0200)//设置某些信息的权限,如进程优先级
#define PROCESS_QUERY_INFORMATION (0x0400)//获得进程信息的权限,如它的退出代码、优先级
#define PROCESS_SUSPEND_RESUME (0x0800)//暂停或恢复进程的权限
#define PROCESS_QUERY_LIMITED_INFORMATION (0x1000)/*获得某些信息的权限,如果获得了PROCESS_QUERY_INFORMATION,也拥有PROCESS_QUERY_LIMITED_INFORMATION权限*/
#define PROCESS_SET_LIMITED_INFORMATION (0x2000)
void 安装内存保护();
void 卸载内存保护();
3.破解 ObRegisterCallbacks 函数的使用限制
第一种方法
在讲解怎么使用 ObRegisterCallbacks 函数来注册系统线程、进程回调的之前,先来讲解下 Windows 对这个函数做的限制:驱动程序必须有数字签名才能使用此函数。不过国外的黑客对此限制很不满,通过逆向 ObRegisterCallbacks,找到了
破解这个限制的方法。经研究,内核通过 MmVerifyCallbackFunction 验证此回调
是否合法, 但此函数只是简单的验证了一下 DriverObject->DriverSection->Flags 的值是不是为 0x20:
具体使用方法如下:
我们在驱动口点加上
#include"进程保护.h"
4.在入口点加上 //定义一个结构来强制的转
typedef struct _KLDR_DATA_TABLE_ENTRY
{
LIST_ENTRY listEntry;
ULONG unknown1;
ULONG unknown2;
ULONG unknown3;
ULONG unknown4;
ULONG unknown5;
ULONG unknown6;
ULONG unknown7;
UNICODE_STRING path;
UNICODE_STRING name;
ULONG Flags;
} KLDR_DATA_TABLE_ENTRY, *PKLDR_DATA_TABLE_ENTRY;
加载驱动代码里面加入破解驱动签名限制代码
PKLDR_DATA_TABLE_ENTRY pobj = (PKLDR_DATA_TABLE_ENTRY)DriverObject->DriverSection;
pobj->Flags |= 0x20;
在创建驱动设备后面,在调用一下
安装内存保护(); //函数
在到驱动卸载里面调用一下
卸载内存保护(); //函数
最后一步
`
开发环境设置方式是:
右击项目,选择属性;
选中配置属性中的链接器,点击命令行;
在其它选项中输入: /INTEGRITYCHECK 表示设置; /INTEGRITYCHECK:NO 表示不设置。
对于使用sources文件编译的方式,增加LINKER_FLAGS=/INTEGRITYCHECK
在Debug 和Release都加上
在命令行加上/INTEGRITYCHECK
虚拟机加载驱动测试结果
卸载驱动才可以结束
以上就是驱动保护的全部代码了。