驱动保护 -- 通过PID保护指定进程

简介: 驱动保护 -- 通过PID保护指定进程

一、设计界面

1、添加一个编辑框输入要保护的进程PID,并添加两个按钮,一个保护进程,一个解除保护

2、右击编辑框,添加变量

二、驱动层代码实现

1、声明一个受保护的进程PID数组

static UINT32 受保护的进程PID[256] = { 0 };

2、添加PID到保护函数

void 添加PID到保护(UINT32 pid) 
{
  for (size_t i = 0; i < 256; i++)
  {
    if (受保护的进程PID[i]==0|| 受保护的进程PID[i]==pid)
    {
      受保护的进程PID[i] = pid;
      break;
    }
  }
}

3、删除PID保护函数

void 删除PID保护(UINT32 pid)
{
  for (size_t i = 0; i < 256; i++)
  {
    if (受保护的进程PID[i] == pid)
    {
      受保护的进程PID[i] = 0;
      break;
    }
  }
}

4、清空PID保护函数

void 清空PID保护()
{
  memset(受保护的进程PID, 0, sizeof(受保护的进程PID));
}

5、PID是否受保护函数

BOOLEAN PID是否受保护(UINT32 pid)
{
  for (size_t i = 0; i < 256; i++)
  {
    if (pid==0)
    {
      return 0;
    }
    if (受保护的进程PID[i] == pid)
    {
      return TRUE;
    }
  }
  return FALSE;
}

6、将函数在头文件声明一下

void 添加PID到保护(UINT32 pid);
void 删除PID保护(UINT32 pid);
void 清空PID保护();
int PID是否受保护(UINT32 pid);

7、获取PID

UINT32 当前进程PID = PsGetCurrentProcessId();
    HANDLE PID = PsGetProcessId((PEPROCESS)OperationInformation->Object);
    if (PID是否受保护(PID)==1)
    {
    DbgPrint("nxyn:sys pEPROCESS=%p ", OperationInformation->Object);
     DbgPrint("nxyn:被保护的PID:%d \n", PID);
      ACCESS_MASK 获取权限 = OperationInformation->Parameters->CreateHandleInformation.OriginalDesiredAccess;
      ACCESS_MASK 获取新权限 = OperationInformation->Parameters->CreateHandleInformation.DesiredAccess;//将句柄权限清零
      //让结束进程的功能失效
      获取权限 &= ~PROCESS_TERMINATE;
      获取权限 &= ~PROCESS_VM_OPERATION;
      获取权限 &= ~PROCESS_VM_WRITE;
      获取权限 &= ~PROCESS_VM_READ;
      //返回我们修改过的权限 OpenProcess
      OperationInformation->Parameters->CreateHandleInformation.DesiredAccess = 获取权限;
      DbgPrint("nxyn:获取权限=%X 获取新权限=%X", 获取权限, 获取新权限);
    }

8、添加控制码

#define irp添加PID到保护   CTL_CODE(FILE_DEVICE_UNKNOWN, 0x804,     METHOD_BUFFERED,FILE_ANY_ACCESS)
#define irp删除PID保护   CTL_CODE(FILE_DEVICE_UNKNOWN, 0x805,     METHOD_BUFFERED,FILE_ANY_ACCESS)

9、通过控制码实现添加和删除保护

else if (控制码== irp添加PID到保护)
    {
      IRP添加PID到保护(IRP指针);
    }
    else if (控制码 == irp删除PID保护)
    {
      IRP删除PID保护(IRP指针);
    }

10、添加和删除的代码具体实现

void IRP添加PID到保护(PIRP IRP指针)
{  
  int* 缓冲区 = (int*)IRP指针->AssociatedIrp.SystemBuffer;
  int 计算结果 = 0;
  if (缓冲区)
  {
    UINT32* pPID = (UINT32*)缓冲区;
    UINT32 pid = pPID[0];
    添加PID到保护(pid);
    IRP指针->IoStatus.Information = sizeof(int);//设置操作的字节数
    IRP指针->IoStatus.Status = STATUS_SUCCESS;//返回状态
    IoCompleteRequest(IRP指针, IO_NO_INCREMENT);//完成一个IRP请求
    KdPrint(("nxyn:PID已添加到保护"));
  }
}
void IRP删除PID保护(PIRP IRP指针)
{
  int* 缓冲区 = (int*)IRP指针->AssociatedIrp.SystemBuffer;
  int 计算结果 = 0;
  if (缓冲区)
  {
    UINT32* pPID = (UINT32*)缓冲区;
    UINT32 pid = pPID[0];
    删除PID保护(pid);
    IRP指针->IoStatus.Information = sizeof(int);//设置操作的字节数
    IRP指针->IoStatus.Status = STATUS_SUCCESS;//返回状态
    IoCompleteRequest(IRP指针, IO_NO_INCREMENT);//完成一个IRP请求
    KdPrint(("nxyn:PID已删除保护"));
  }
}

三、应用层代码实现

1、添加控制码

#define irp添加PID到保护   CTL_CODE(FILE_DEVICE_UNKNOWN, 0x804,     METHOD_BUFFERED,FILE_ANY_ACCESS)
#define irp删除PID保护   CTL_CODE(FILE_DEVICE_UNKNOWN, 0x805,     METHOD_BUFFERED,FILE_ANY_ACCESS)

2、双击保护进程按钮

UpdateData(TRUE);//将窗口的数据更新到变量
  char 缓存区[256];
  sprintf_s(缓存区, "nxyn:应用程序保护PID控制码为%X\n", irp添加PID到保护);
  OutputDebugStringA(缓存区);
  UINT32 输入数据 = m_PID;
  int 返回数据;
  DWORD 实际读取字节数;
  DeviceIoControl(
    设备句柄,
    irp添加PID到保护,
    &输入数据,
    sizeof(输入数据),
    &返回数据,
    sizeof(返回数据),
    &实际读取字节数,
    NULL);

3、双击解除进程保护按钮

UpdateData(TRUE);//将窗口的数据更新到变量
  char 缓存区[256];
  sprintf_s(缓存区, "nxyn:应用程序删除PID控制码为%X\n", irp删除PID保护);
  OutputDebugStringA(缓存区);
  UINT32 输入数据 = m_PID;
  int 返回数据;
  DWORD 实际读取字节数;
  DeviceIoControl(
    设备句柄,
    irp删除PID保护,
    &输入数据,
    sizeof(输入数据),
    &返回数据,
    sizeof(返回数据),
    &实际读取字节数,
    NULL);

四、测试应用

目录
相关文章
|
1月前
|
Linux Shell
【Linux】解决:为什么重复创建同一个【进程pid会变化,而ppid父进程id不变?】
【Linux】解决:为什么重复创建同一个【进程pid会变化,而ppid父进程id不变?】
|
1月前
2023驱动保护学习 -- 通过驱动保护进程
2023驱动保护学习 -- 通过驱动保护进程
26 0
|
1月前
|
监控 Unix Linux
C语言进程(第一章进程基础,fork()函数,pid_t, pid, getpid())
C语言进程(第一章进程基础,fork()函数,pid_t, pid, getpid())
139 0
|
6月前
|
Windows
5.4 Windows驱动开发:内核通过PEB取进程参数
PEB结构`(Process Envirorment Block Structure)`其中文名是进程环境块信息,进程环境块内部包含了进程运行的详细参数信息,每一个进程在运行后都会存在一个特有的PEB结构,通过附加进程并遍历这段结构即可得到非常多的有用信息。在应用层下,如果想要得到PEB的基地址只需要取`fs:[0x30]`即可,TEB线程环境块则是`fs:[0x18]`,如果在内核层想要得到应用层进程的PEB信息我们需要调用特定的内核函数来获取。
64 0
5.4 Windows驱动开发:内核通过PEB取进程参数
|
6月前
|
监控 安全 API
7.1 Windows驱动开发:内核监控进程与线程回调
在前面的文章中`LyShark`一直在重复的实现对系统底层模块的枚举,今天我们将展开一个新的话题,内核监控,我们以`监控进程线程`创建为例,在`Win10`系统中监控进程与线程可以使用微软提供给我们的两个新函数来实现,此类函数的原理是创建一个回调事件,当有进程或线程被创建或者注销时,系统会通过回调机制将该进程相关信息优先返回给我们自己的函数待处理结束后再转向系统层。
74 0
7.1 Windows驱动开发:内核监控进程与线程回调
|
6月前
|
存储 Windows
4.6 Windows驱动开发:内核遍历进程VAD结构体
在上一篇文章`《内核中实现Dump进程转储》`中我们实现了ARK工具的转存功能,本篇文章继续以内存为出发点介绍`VAD`结构,该结构的全程是`Virtual Address Descriptor`即`虚拟地址描述符`,VAD是一个`AVL`自`平衡二叉树`,树的每一个节点代表一段虚拟地址空间。程序中的代码段,数据段,堆段都会各种占用一个或多个`VAD`节点,由一个`MMVAD`结构完整描述。
64 0
4.6 Windows驱动开发:内核遍历进程VAD结构体
|
6月前
|
存储 数据安全/隐私保护 Windows
4.5 Windows驱动开发:内核中实现进程数据转储
多数ARK反内核工具中都存在驱动级别的内存转存功能,该功能可以将应用层中运行进程的内存镜像转存到特定目录下,内存转存功能在应对加壳程序的分析尤为重要,当进程在内存中解码后,我们可以很容易的将内存镜像导出,从而更好的对样本进行分析,当然某些加密壳可能无效但绝大多数情况下是可以被转存的。
35 0
4.5 Windows驱动开发:内核中实现进程数据转储
|
3天前
|
存储 Linux Shell
Linux进程概念(上)
冯·诺依曼体系结构概述,包括存储程序概念,程序控制及五大组件(运算器、控制器、存储器、输入设备、输出设备)。程序和数据混合存储,通过内存执行指令。现代计算机以此为基础,但面临速度瓶颈问题,如缓存层次结构解决内存访问速度问题。操作系统作为核心管理软件,负责资源分配,包括进程、内存、文件和驱动管理。进程是程序执行实例,拥有进程控制块(PCB),如Linux中的task_struct。创建和管理进程涉及系统调用,如fork()用于创建新进程。
17 3
Linux进程概念(上)
|
3天前
|
缓存 监控 安全
Linux top命令详解:持续监听进程运行状态
Linux top命令详解:持续监听进程运行状态
16 3
|
8天前
|
Linux 数据处理
深入了解Linux命令kill:终止进程的艺术
**Linux的`kill`命令详解:高效管理进程的工具** `kill`命令在Linux中用于向进程发送信号,如SIGTERM(默认)和SIGKILL,以终止或影响进程行为。它通过进程ID(PID)操作,支持多种信号和选项,如`-l`列出信号,`-9`强制杀进程。例如,`kill 1234`发送TERM信号,`kill -9 1234`发送KILL信号。使用时注意,SIGKILL是不可忽视的,可能导致数据丢失。配合`pgrep`和`pkill`能更灵活管理进程。了解进程依赖和使用其他命令如`ps`和`top`可优化系统资源管理。

相关实验场景

更多