当前位置: 首页 > article >正文

IRP默认最小流程

IRP是Windows内核中的一种非常重要的数据结构。上层应用程序与底层驱动程序通信时,应用程序会发出I/O请求,操作系统将相应的I/O请求转换成相应的IRP,不同的IRP会根据类型被分派到不同的派遣例程中进行处理。

irp相当于R3下的消息,应用程序对驱动程序进行操作的时候会发出相应的消息,驱动程序根据这些消息做出相应的操作。这些操作通过我们自己编写的派遣函数来决定执行什么样的操作。

当应用层调用 ReadFile WriteFile CreateFile CloseHandle 等WINAPI 函数 则会产生对应的IRP类型,这些IRP 也就是 IRP_MJ_CREATE IRP_MJ_WRITE IRP_MJ_READ IRP_MJ_CLOSE 并且传送到驱动的中的派遣函数中。

另外 内核中的 I/O 处理函数也会产生IRP,所以可见IRP并不完全是由应用层产生的。比如内核中的 Zw系列开头的文件操作 一样会产生IRP。

IRP类型

来源

IRP_MJ_CREATE

CreateFile/ZwCreateFile

IRP_MJ_READ

ReadFile/ZwReadFile

IRP_MJ_WRITE

WriteFile/ZwWriteFile

IRP_MJ_CLOSE

CloseHandle/ZwClose

...

...

...

...

 程序流程:

1.创建设备与符号链接

2.为所有IRP类型设置为默认派遣函数

3.为不同的IRP类型设置派遣函数

4.编写派遣函数来处理收到不懂类型的IRP的不同操作

5.在卸载函数中删除设备与符号链接


设备对象的通信方式

1.基于缓存方式(DO_BUFFERED_IO):

写入:R0把R3缓冲区的数据复制一份到R0缓冲区里面,写出:R0把数据写入到R3的缓冲区里面

2.直接读写方式(DO_DIRECT_IO):

R3和R0访问同一块物理页

3.两者皆不方式(DO_FORCE_NEITHER_IO):

写入:R0直接读取R3的缓冲区,写出:R0直接写入R3的缓冲区

<直接读写方式> 和 <两者皆不方式>很类似,都是直接访问R3的内存地址,但<直接读写方式>有内存映射机制开销比<两者皆不方式>大,然而<基于缓存方式>最安全。


驱动代码:

#include <ntddk.h>

#define DEVICE_NAME L"\\device\\MyDricer1" //设备对象名称
#define LINK_NAME L"\\dosdevices\\Goose" //符号链接名称

VOID UnDirver(PDRIVER_OBJECT pDriverObj)
{
	UNICODE_STRING uLinkName = RTL_CONSTANT_STRING(LINK_NAME);//初始化符号链接名称
	IoDeleteSymbolicLink(&uLinkName);//删除符号链接
	IoDeleteDevice(pDriverObj->DeviceObject);//删除设备对象
	DbgPrint("Driver Unloaded.\n");
}

NTSTATUS MyMajor(PDEVICE_OBJECT Device, PIRP irp)
{
	irp->IoStatus.Status = STATUS_SUCCESS;//设置irp处理成功
	irp->IoStatus.Information = 0;//设置返回的字节数
	IoCompleteRequest(irp, IO_NO_INCREMENT);//结束irp处理流程
	DbgPrint("MyMajor");//打印测试
	return STATUS_SUCCESS;
}

NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObj, PUNICODE_STRING pRegPath) 
{
	pDriverObj->DriverUnload = UnDirver;

	UNICODE_STRING uDeviceName = RTL_CONSTANT_STRING(DEVICE_NAME);//初始化设备名称
	UNICODE_STRING uLinkName = RTL_CONSTANT_STRING(LINK_NAME);//初始化符号链接名称
	PDEVICE_OBJECT pDeviceObject = NULL;
	NTSTATUS ntStatus = IoCreateDevice(pDriverObj, 0, &uDeviceName, FILE_DEVICE_UNKNOWN, 0, TRUE, &pDeviceObject);//创建一个设备对象
	if (ntStatus != STATUS_SUCCESS)
	{
		DbgPrint("IoCreateDevice failed:%x\n", ntStatus);
		return ntStatus;
	}
	pDeviceObject->Flags |= DO_BUFFERED_IO;//设置设备对象的通信方式:1.基于缓存方式 2.直接读写方式 3.两者皆不方式
	ntStatus = IoCreateSymbolicLink(&uLinkName, &uDeviceName);//把设备对象和链接名称进行绑定,R3可以通过链接名称访问
	if (ntStatus != STATUS_SUCCESS)
	{
		IoDeleteDevice(pDeviceObject);//删除设备对象
		DbgPrint("IoCreateSymbolicLink failed:%x\n", ntStatus);
		return ntStatus;
	}
	//驱动对象的所有irp回调函数,设置成我的回调函数
	for (size_t i = 0; i < IRP_MJ_MAXIMUM_FUNCTION + 1; i++)
	{
		pDriverObj->MajorFunction[i] = MyMajor;
	}

	return STATUS_SUCCESS;
}

应用代码:

#include <iostream>
#include <windows.h>

#define LINK_NAME L"\\\\.\\Goose" //符号链接名称

int main()
{
    HANDLE hRet = CreateFile(LINK_NAME, GENERIC_ALL, NULL, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    if (hRet == INVALID_HANDLE_VALUE)
    {
        printf("CreateFile failed:%x\n", GetLastError());
        system("pause");
        return 0;
    }
    DWORD dwRetSize;
    WriteFile(hRet, L"123", 8, &dwRetSize, NULL);
    printf("收到数据大小:%d\n", dwRetSize);
    system("pause");
    return 0;
}



http://www.kler.cn/news/350620.html

相关文章:

  • 【TFR-Net】基于transformer的鲁棒多模态情感分析特征重构网络
  • django5入门【03】新建一个hello界面
  • vue写个表格,让它滚动起来,没有用datav,有的时候结合会出错,一种简单的方法,直接用animation
  • 构建未来:AI初创企业的投资桥梁 —— AI Angels Fund
  • 面经之一:Synchronized与ReentrantLock区别
  • python pandas 1
  • 2023年“网络建设与运维”广西省赛试题复盘
  • yakit使用教程(四,信息收集)
  • WorkFlow GO-Task 源码分析
  • 简单说说mysql中一条读sql是如何执行的
  • 2023年12月中国电子学会青少年软件编程(Python)等级考试试卷(一级)答案 + 解析
  • PowerShell中conda activate指令无效的问题
  • CentOS硬解码+ffmpeg+Nvidia硬解码
  • 探索人工智能在数学教育上的应用——使用大规模语言模型解决数学问题的潜力和挑战
  • 学习 Python 的途径
  • 基于深度学习的车辆车型检测识别系统(YOLOV5)
  • 太速科技-456-FMCJ456-14bit 2通道3/2.6/2GS/s ADC +16bit 2通道12.6GS/s DAC FMC AD/DA子卡
  • WSL2配置代理解决git网络不通畅的问题
  • React Native学习计划
  • STM32—WDG看门狗
  • Palo Alto Networks Expedition 未授权SQL注入漏洞复现(CVE-2024-9465)
  • 基于Spring Boot的大创项目成本控制系统
  • 使用rabbitmq-operator在k8s集群上部署rabbitmq实例
  • js高级-理解call()的原理
  • Java基础15-Java高级
  • Leetcode—1188. 设计有限阻塞队列【中等】(多线程)