驱动使用 MDL 方式读写内存

32位/64位WINDOWS驱动之突破进程保护写只读内存驱动3 此方法相当于CE附加程序,然后进行写入只读的内存地址中(原理就是对只读内存地址进行赋予了写的权限)0x400000MmGetSystemAddressForMdlSafe 进行实际的映射操作,并设置MdlFlags的MDL_MAPPED_TO_SYSTEM_VA标志。MmProbeAndLockPages 并不将物理页面映射到内核地址空间,而仅锁定物理页面。 阅读详情
AI摘要

本文介绍了一种使用MDL(内存描述符列表)在内核模式下修改内存的有效方法,适用于32位和64位内核。通过创建MDL、更新物理内存描述并映射到虚拟内存,实现对指定内核内存数据的安全修改。

背景

通常,我们在内核中修改内存的时候,都是通过修改 CR0 寄存器,关闭内存写保护属性,然后再写入内存的方式来修改内存。我个人不喜欢这种方式,因为总感觉我们使用没有线程接口函数的方法,总感觉不太稳定,而且,在 64 位程序下,CR0 方式不再适用了。

所以,我强烈推荐在内核下使用 MDL 方式来修改内存,在 32 位内核和 64 位内核下同样有效。

实现过程

内存描述符列表 (MDL) 是一个系统定义的结构,通过一系列物理地址描述缓冲区。MDL的全称是 Memory Descriptor List,即内存描述符表。可以通过MDL描述一块内存区域,在MDL中包含了该内存区域的起始地址、拥有者进程、字节数量、标记等信息。

MDL 是用来建立一块虚拟地址空间与物理页面之间的映射。对这句话的理解是使用 MDL 来修改内核内存的关键。当我们要对一块内核内存进行修改的时候,我们先为这块内存创建 MDL,那么就会建立一块新的虚拟内存空间,与将要修改内存对应的物理空间相映射。也就是说,同一块物理空间,映射了两块不同的虚拟内存地址。我们可以通过这两个虚拟内存地址,来操作这块物理内存,这便是 MDL 修改内存的实现思路。

那么,使用 MDL 方式修改内存具体的实现流程如下:

  • 首先,给定缓冲区的起始地址和长度,调用 MmCreateMdl 函数分配一个足够大的 MDL 结构来映射给定的缓冲区
  • 然后,调用 MmBuildMdlForNonPagedPool 函数来更新 MDL 对物理内存的描述。
  • 最后,调用 MmMapLockedPages 函数将 MDL 中描述的物理页面映射到虚拟内存中,并返回映射的虚拟内存地址,这样我们就可以通过新映射的虚拟内存地址,操作同一块物理页面了,以此实现修改指定内存的数据。

代码:

    BOOLEAN MDLWriteMemory(PVOID pBaseAddress, PVOID pWriteData, SIZE_T writeDataSize)
    {
        PMDL pMdl = NULL;
        PVOID pNewAddress = NULL;
        // 创建 MDL
        pMdl = MmCreateMdl(NULL, pBaseAddress, writeDataSize);
        if (NULL == pMdl)
        {
            return FALSE;
        }
        // 更新 MDL 对物理内存的描述
        MmBuildMdlForNonPagedPool(pMdl);
        // 映射到虚拟内存中
          pNewAddress = MmMapLockedPages(pMdl, KernelMode);
        if (NULL == pNewAddress)
        {
            IoFreeMdl(pMdl);
        }
        // 写入数据
        RtlCopyMemory(pNewAddress, pWriteData, writeDataSize);
        // 释放
        MmUnmapLockedPages(pNewAddress, pMdl);
        IoFreeMdl(pMdl);
        return TRUE;
    }
内核上项目【读内存的几种方式】 在内核编程有时为了能够读取目标三环进程的内存,主要有以下几种不错的方式1.附加后通过直接memcpy复制目标内存进行读取,但是这种方式非常不稳定,不推荐2.使用MmCopyVirtualMemory进行读取,因为这是微软写好的一个内核函数,所以异常分发等都完善可以直接使用3.切换CR3读取,当切换了CR3时,访问的地址都将以CR3为目录项基址,所以可以直接访问到目标进程的内存4.使用MDL方式,附加进程然后将物理页上的内容映射一份到了内核,进而通过memcpy对映射后的地址进行拷贝即可。 阅读详情

相关推荐

Windows驱动开发WDM (3)- 设备内存读写方式

驱动所创建的设备一般有3种方式:缓冲区方式,直接方式和其他方式(对应DO_BUFFERED_IO, DO_DIRECT_IO和0)。 比如: fdo->Flags |= DO_BUFFERED_IO DO_BUFFERED_IO指定当前设备以缓冲区方式工作。 通常用户模式和内核模式交互的时候,用户模式会传一个buffer进来,注意:这个buffer是用户模式的虚拟地址。尽管驱动程序可以访问

zj510的专栏 7012

驱动开发:内核MDL读写进程内存

MDL内存读写是最常用的一种读写模式,通常需要附加到指定进程空间内然后调用内存拷贝得到对端内存中的数据,在调用结束后再将其空间释放掉,通过这种方式实现内存读写操作,此种模式的读写操作也是最推荐使用的相比于CR3切换来说,此方式更稳定并不会受寄存器的影响。写入时与读取类似,只是多了锁定页面和解锁操作。

微软技术分享 2万+

驱动开发之 设备读写方式:缓冲区方式

1. 设备对象一共有三种读写方式:缓冲区方式读写(Buffered方式);直接方式读写(Direct方式);Neither方式。这三种方式的Flags分别对应DO_BUFFERED_IO,DO_DIRECT_IO,0 在buffered方式中,I/O管理器先创建一个与用户模式数据缓冲区大小相等的系统缓冲区。而你的驱动程序将使用这个系统缓冲区工作。I/O管理器负责在系统缓冲区和用户模式缓冲区之间

Lydia的博客 3907

使用MDL读写内存的SSDT HOOK

X64下有patchguard,所以先讨论x86的 思路 首先找到函数地址,如果是导出函数,可以使用MmGetSystemRoutineAddress,如果未导出加载符号通过特征码 实现新新函数替换原函数 恢复函数 关于系统从应用层进入内核,xp前是int2e,之后32位是sysenter,64是syscall https://bbs.pediy.com/thread-226254.h...

kernweak的博客 2535

子阳驱动读写修复可编译版 带mdl强读写 易语言+C++源码

摘要: "子阳驱动读写修复"是一款融合易语言与C++的磁盘修复工具,具备跨进程内存读写、强错误修复能力等特性。软件采用易语言开发界面,C++实现底层操作,通过模块化设计支持可编译性。功能包括坏道识别、丢失簇修复等,使用时需注意数据备份。该工具适用于合法数据恢复需求,提供技术探讨用途的源码下载。

wuyoula的博客 755

Windows 驱动内存读写:3种内核模式实现对比(CR3/MDL/物理映射)

本文深入解析Windows内核驱动内存读写的三种主流技术:CR3寄存器切换、MDL内存映射和物理内存直接访问,对比分析其原理、性能、隐蔽性和兼容性。通过实际代码示例和选型指南,帮助开发者在系统调试、安全防护等场景中选择最适合的内存操作方案,提升驱动开发效率与稳定性。

weixin_28340315的博客 370

驱动开发之 设备读写方式:直接读写方式

驱动开发之 设备读写方式:直接方式 上一节介绍了缓冲区方式读写,这一节咱们来看看直接方式读写设备。 1. 直接方式读写设备,操作系统会将用户模式下的缓冲区锁住,然后操作系统将这段缓冲区在内核模式地址再次映射一遍。这样,用户模式的缓冲区和内核模式的缓冲区指向的是同一区域的物理内存。无论操作系统如何切换进程,内核模式地址都保持不变。 创建好设备IoCreateDevice后,需要设置DO_DI...

weixin_34153893的博客 413

Day470&471.Netty概述&Netty高性能架构设计 -netty

Netty概述 一、原生 NIO 存在的问题 NIO 的类库和 API 繁杂,使用麻烦:需要熟练掌握 Selector、ServerSocketChannel、SocketChannel、ByteBuffer等。 需要具备其他的额外技能:要熟悉 Java 多线程编程,因为 NIO 编程涉及到 Reactor 模式,你必须对多线程和网络编程非常熟悉,才能编写出高质量的 NIO 程序。 开发工作量和难度都非常大:例如客户端面临断连重连、网络闪断、半包读写、失败缓存、网络拥塞和异常流的处理等等。 JDK NIO

阿昌爱Java 1571

Windows内核驱动中的派遣函数

驱动程序的一个重要功能就是处理IO请求,其中大部分IO请求都是在派遣函数中完成的。在用户模式下对内核驱动发出的IO请求,全部都由系统转化为一个IRP(IO请求包),不同的IRP会被派遣到不同的派遣函数中进行处理。这有点类似于Windows中的消息机制。

静下心来,做好每一件事 737

博图编写温度程序_s7 smart200的CRC-16校验程序

最近做一个小项目,项目中采用485自由口通讯方式,使用一台西门子S7 smart200对一台冷水机做多个状态和温度做监控,并能对冷水机进行启停控制,和参数设置,因为冷水机的协议不是标准modbus格式,所以要自己编写通信协议。其中要用到CRC校验,在网上找了些别人写的程序,基本上用不了。只能自力更生了。首先,找到CRC校验的算法,并理解。 下面就是我找的算法(这个网上很多),1....

weixin_39539761的博客 3062

直流无刷减速电机选型指南:从KV值到霍尔传感器,新手必看的5个关键参数

本文详细解析直流无刷减速电机选型的5个关键参数,包括KV值、转矩、电流与功率、减速比选择以及霍尔传感器配置。通过实战案例和避坑策略,帮助工程师精准匹配电机性能与负载需求,提升工业自动化设备的可靠性和效率。特别强调霍尔传感器在精准控制中的关键作用。

alice7model的博客 620

3.3 Windows驱动开发:内核MDL读写进程内存

MDL内存读写是一种通过创建MDL结构体来实现跨进程内存读写的方式。在Windows操作系统中,每个进程都有自己独立的虚拟地址空间,不同进程之间的内存空间是隔离的。因此,要在一个进程中读取或写入另一个进程的内存数据,需要先将目标进程的物理内存映射到当前进程的虚拟地址空间中,然后才能进行内存读写操作。MDL结构体是Windows内核中专门用于描述物理内存的数据结构,它包含了一系列的数据元素,包括物理地址、长度、内存映射的虚拟地址等信息。

微软技术分享 6713

【笔记】2022.6.7 数据分析概论

已完结

SpriteNym的博客 1372

驱动读写应用程序内存

用驱动读写应用程序的内存

吾无法无天的博客 8135

三菱FX5U气缸控制功能块(完整ST源代码+示例程序)

如果机器包含100个气缸,我们只需要修改数组的元素数量就可以了,效率非常的高。待续....博途PLC 面向对象系列之“双通气缸功能块“(SCL代码)_plc面向对象-优快云博客文章浏览阅读667次。本文介绍了博途PLC中面向对象编程的应用,重点讲解了双通气缸的功能块设计,包括双通电磁阀功能块、双通气缸的UDT数据类型以及SCL代码实现。同时,对比了双通与单通电磁阀的差异,并讨论了将单通气缸改造为双通气缸的方法,强调了双通气缸在安全性上的优势。

RXXW_Dor的博客 1027

UNet 改进(3):CBAM模块的融合创新

CBAM模块可以灵活地添加到网络的不同位置,本实现选择在初始卷积后添加,既提升了性能又不过度增加计算负担。UNet_CBAM通过集成注意力机制,使网络能够自动聚焦于图像中最相关的区域和特征通道,从而提升了分割性能。然而,传统的UNet在处理复杂场景时,对所有空间位置和通道特征一视同仁,这可能导致对重要特征的关注不足。在实际应用中,特别是在医学图像分析等需要精确分割的场景中,UNet_CBAM展现出了优异的性能。:CBAM添加的计算量很小,却能带来显著的性能提升,具有很好的性价比。

2401_82355416的博客 1642

驱动开发:内核读写内存浮点数

将其转换为浮点数,通过此方法即可实现字节集到浮点数的转换,而决定是单精度还是双精度则只是一个字节集长度问题,这段读写代码实现原理如下所示;此处只用于演示核心原理,如果想要实现不报错,该代码中的传值操作应在应用层进行,而传入参数也应改为字节类型即可。读写,本章将在如前所述的读写函数进一步封装,并以此来实现驱动读写内存浮点数的目的。浮点数的目的,实现原理是通过读取BYTE类型的前4或者8字节的数据,并通过。的实现,因为浮点数本质上也可以看作是一个字节集,对于。函数依次循环字节集列表即可实现写出字节集的目的;

微软技术分享 2万+

Flowise智能调度系统设计与实现

本文深入探讨Flowise平台的智能调度系统设计与实现,包括调度模型、调度策略、调度优化、调度应用等方面。通过详细的设计方案和实现策略,帮助开发者构建智能的调度系统。本文详细介绍了Flowise平台的智能调度系统设计与实现,包括调度模型、调度策略、调度优化、调度应用等方面。通过详细的设计方案和实现策略,帮助开发者构建智能的调度系统。

加入“Super Entity”,与全能开发团队共探AI智能体与数字人项目,开启前沿技术之旅。 1017

MDL驱动读写

过去常用的一种R3虚拟内存读写的思路和特点->MFL读写内存

CchengXxiaoZzhon的博客 155

信号处理算法:离散余弦变换(DCT)_(1).离散余弦变换(DCT)概述

离散余弦变换的数学定义如下:对于一个长度为NNN的离散信号xnx(n)xn,其DCT变换后的系数XkX(k)XkXk∑n0N−1xncos⁡πNn12kk012N−1Xkn0∑N−1​xncosNπ​n21​kk012N−1其中,kkk是频率指数,nnn是时间或空间索引。离散余弦变换(DCT)是一种强大的信号处理技术,广泛应用于图像压缩、音频处理、数据压缩等领域。

2401_87715305的博客 1554

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

驱动开发之 设备读写方式:直接方式

上一节介绍了缓冲区方式读写,这一节咱们来看看直接方式读写设备。 1. 直接方式读写设备,操作系统会将用户模式下的缓冲区锁住,然后操作系统将这段缓冲区在内核模式地址再次映射一遍。这样,用户模式的缓冲区和内核模式的缓冲区指向的是同一区域的物理内存。无论操作系统如何切换进程,内核模式地址都保持不变。 创建好设备IoCreateDevice后,需要设置DO_DIRECT_IO,  pDevObj

Lydia的博客 3936

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

28.实现MDL驱动读写-Windows驱动

驱动 MDL 游戏逆向 游戏安全 游戏攻防 c++ 反游戏外挂 保姆级攻略 Windows 汇编 x64游戏

计算机王的博客 847

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

MDL修改内核内存实现

NTSTATUS DriverEntry(PDRIVER_OBJECT driver,PUNICODE_STRING reg) { PMDL mdl; PVOID addrMm; ULONG addrKdEnterDebugger; ULONG addrKdEnteredDebugger; UNICODE_STRING func; ULONG addr = 0; RtlInitUnicodeStr...

haodawei123的博客 3309

Windows驱动开发(一) MDL驱动读写

使用MDL驱动读写应该是最常见的读写内存方式 不多说 直接上代码 typedef struct TongL_Process { ULONG pid; //进程ID ULONG64 Address; //内存地址 ULONG64 buf; //缓冲区指针 ULONG Size; //内存大小 }TongL_PROCESS, * PTongL_PROCESS; 读: PTongL_PROCESS pInputData = (PTongL_

qq_33789853的博客 2311
上一篇: c++ 在内存中加载 exe/dll (不使用CreateProcess、LoadLibrary 等 API)
下一篇: C++ 修改指定进程 PEB 中路径和命令行信息实现进程伪装
(-: LYSM :-)
博客等级 码龄10年 428粉丝 273原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值