☰
强制CR3驱动读写
2026/10/14 16:20:47 网站建设 项目流程
作者:没钱的诚终
  1. 书接上文:

通过KeStackAttachProcess实现赋值CR3切换线程上下文,但是这个函数会留下使用痕迹,容易被反作弊查到

  1. 解决思路:

取KeStackAttachProcess函数最主要的行为,手动实现KeStackAttachProcess功能

(读取目标进程的CR3,直接写入 CR3寄存器实现进程上下文切换)

  1. 预备

CR3:硬件寄存器 装着「当前这个进程页表的物理起始地址」

代表CPU核心正在执行的R3层的一块独立的虚拟内存(目标进程)

内核CR3 :是完整页表,同时映射内核空间和用户空间。

用户CR3 :只映射极少量内核代码,主要映射用户空间。

注意这俩个CR3的值可能相等 目的都是为了把虚拟地址翻译成物理地址

这里的虚拟地址可以是R3或者R0 但是用户层对于翻译R0有点局限(物理页中可能没有此地址)

注意:用户CR3下不能读写内核虚拟内存(代码中就0x28偏移 无其他可选)

  1. 原理:

通过修改CR3的值使CPU执行目标进程的代码

同时防止物理页发生错页等问题,将中断等级(IRQL)提升至DPC_lEVEL以应对线程调度(中断和APC)

即:当线程调度时 CR3会受到牵连发生变化 (而KeStackAttachProcess中有提等级的部分代码)

  1. 注意部分

1.由于CR3会切换线程上下文,那么如果中途发生中断(高等级IRQL)会抢占CPU线程,另一个APC会在空闲时(线程等待)处理APC队列 从而使CR3又发生赋值,

进而导致无法读取正确的R3层指针最后蓝屏

  1. CR3有两种类型 如果切换至R3层的CR3 则无法访问内核虚拟内存,
  2. MmIsAddressValid此函数用于查询虚拟地址对应的物理分页是否存在,但是只是瞬时,无法在执行拷贝时保证真的存在
  3. ProbeForRead此函数只能在PASSIVE_LEVEL等级下执行 高等级直接蓝屏,且无法验证所对应的物理页是否存在

5.代码部分

  1. 关键函数分析
  1. _disable();暂停中断 解决中断引起的线程调度
  2. _enable();还原中断
  3. KeRaiseIrqlToDpcLevel()提升IRQL等级至DPC_LEVEL 应对APC和低等级中断
  4. KeLowerIrql还原等级
  5. __readcr3();获取当前CR3的值
  6. __writecr3;修改CR3的值

注意:_disable()和KeRaiseIrqlToDpcLevel()都可以临时解决线程调度的问题

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询