<读书笔记>Windows内核安全——第五章磁盘的虚拟

本章深入探讨了WDK中的RAM Disk工程,通过直接操作非分页内存实现高性能虚拟磁盘,同时阐述了其内存占用大及数据易失的特点。文章详细介绍了驱动的入口函数、基于KMDF模型的驱动开发流程、WDF队列的使用方法,以及如何初始化FAT磁盘等关键步骤。此外,还提供了注册表读写、驱动基本使用流程、FAT驱动初始化过程的学习资源。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本章主要说的是WDK中的ramdisk的工程,该工程实现了一个非分页内存(nopaged memory)作为磁盘虚拟空间,虚拟了一个FAT虚拟盘。

该虚拟盘有以下特点:1)性能比一般磁盘高,因为直接是操作的飞分页内存,所以读写速度比较快;2)占用了大量的内存,因为该工程的虚拟空间使用的飞分页内存,所以占用了大量的内存;3)该磁盘每次重启电脑后数据都会丢失,不具有易失性。

该工程使用WDF模型开发,该驱动模型是微软在发布Vista系统时一起发布的驱动开发模型,分为UserMode(UMDF)和KernelMode(KMDF)两种模型,RamDisk是基于KMDF开发,这边真想吐槽一下UMDF,很多功能不能使用,让人很蛋疼的感觉。

 

RamDisk入口函数:

不论是KMDF还是WDM模型的入口函数,默认都是DriverEntry。

NTSTATUS
DriverEntry(
    IN PDRIVER_OBJECT DriverObject,   //驱动对象
    IN PUNICODE_STRING RegistryPath   //该驱动在注册表中信息存放的对应位置 //HKLM\SYSTEM\CurrentControlSet\Services
    )

WDM驱动中DriverEntry会设置对应主功能号的分发函数,但是在WDF中就没有这样的需求,主要的任务是创建一个WDF的驱动对象,以及该该设备的添加函数(AddDevice),对应的分发函数则是在AddDevice中进行设置。

WDF_DRIVER_CONFIG_INIT( &config, RamDiskEvtDeviceAdd );
    return WdfDriverCreate(DriverObject, 
                                RegistryPath, 
                                WDF_NO_OBJECT_ATTRIBUTES, 
                                &config, 
                                WDF_NO_HANDLE);

RamDisk Device添加函数

WdfDeviceInitSetDeviceType(DeviceInit, FILE_DEVICE_DISK);
    WdfDeviceInitSetIoType(DeviceInit, WdfDeviceIoDirect);
    WdfDeviceInitSetExclusive(DeviceInit, FALSE);

第一步是设备设备的属性为磁盘设备属性,读写的IO类型为DIRECT方式,这类方式将缓冲区直接映射到内存中,读写速度快,Exclusive属性设置为FALSE,表示设备可以多次打开。

第二步调用WdfDeviceCreate创建对应的设备对象。

第三步创建读写队列,该队列用于处理读写的请求。WDF中队列的使用相当方便,不用像WDM那样要自己处理,WDF队列可以使用一下三种类型

1)             WdfIoQueueDispatchSequential:连续分发队列,必须在上一个请求完成之后才能进行下一个请求操作;

2)             WdfIoQueueDispatchParallel:并行分发队列,只要请求准备好,就可以执行该请求操作;

3)             WdfIoQueueDispatchManual:手动分发队列,该队列的请求需要用户每次调用IoQueueRetrieveNextRequest去获取下一个请求操作,然后再去执行获取得到的请求。

WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE (
        &ioQueueConfig,
        WdfIoQueueDispatchSequential
        );
ioQueueConfig.EvtIoDeviceControl = RamDiskEvtIoDeviceControl;
ioQueueConfig.EvtIoRead            = RamDiskEvtIoRead;
ioQueueConfig.EvtIoWrite           = RamDiskEvtIoWrite;
WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&queueAttributes, QUEUE_EXTENSION);
status = WdfIoQueueCreate( device,
                               &ioQueueConfig,
                               &queueAttributes,
                               &queue );

第四步初始化驱动中的一些参数,在这里面还有一个很有意思的读写注册表的例子,使用函数RtlQueryRegistryValues读写一串注册表,这种方式可以一次性读取多个注册表的参数该函数可以参见

MSDN  http://msdn.microsoft.com/en-us/library/windows/hardware/ff562046(v=vs.85).aspx

第五步建立一个符号链接,用于上层去调用。这边有个工具WinObj可以查询系统所有的符号链接相关的信息,当创建这个链接之后可以通过该工具查看是否需存在。

 

RamDisk 初始化FAT磁盘

FAT的spec微软是直接给出的,可以到

http://msdn.microsoft.com/en-US/windows/hardware/gg463084处下载,根据这个spec再看代码就能很好的理解,具体的可以参照源码中的写法。

 

读写回调函数中请求的处理

这类请求的操作分为四种类型,1)重新排列,将该请求放到另一队列等待其它的处理函数去处理;2)完成请求;3)撤销请求;4)转发请求,将该请求转发给其它设备。该项目中对请求的处理注意好数据的存放位置就好,其它的都还算是比较简单。

本章几个比较实用的点:注册表的读写、WDF队列的使用、WDF驱动的基本使用流程、如果有搞FAT驱动的,看一下初始化的过程也是很有意义的。
<?php $username = $_POST["username"] ; $password = $_POST["password"] ; if($username === "admin" && $password === "admin1") { // 读取所有笔记文件 $notes = []; $note_files = glob('notes/*.txt'); foreach ($note_files as $file) { $id = basename($file, '.txt'); $content = file_get_contents($file); $notes[$id] = $content; } ?> <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>读书笔记系统</title> <link rel="stylesheet" href="styles.css"> </head> <body> <script> alert('登陆成功'); </script> <div class="container"> <h1>我的读书笔记</h1> <form action="add_note.php" method="post" class="note-form"> <h2>添加新笔记</h2> <div class="form-group"> <label for="book_title">书名:</label> <input type="text" id="book_title" name="book_title" required> </div> <div class="form-group"> <label for="note_content">笔记内容:</label> <textarea id="note_content" name="note_content" rows="5" required></textarea> </div> <button type="submit">保存笔记</button> </form> <div class="notes-list"> <h2>我的笔记</h2> <?php if (empty($notes)): ?> <p>暂无笔记,添加你的第一条读书笔记吧!</p> <?php else: ?> <?php foreach ($notes as $id => $content): ?> <div class="note-card"> <div class="note-content"><?= nl2br(htmlspecialchars($content)) ?></div> <form action="delete_note.php" method="post" class="delete-form"> <input type="hidden" name="note_id" value="<?= $id ?>"> <button type="submit" class="delete-btn">删除</button> </form> </div> <?php endforeach; ?> <?php endif; ?> </div> </div> </body> </html> <?php } else { echo "<script>alert('账号或者密码不正确');</script>"; } ?>
最新发布
07-26
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值