【IRP】Windows 驱动之IRP

什么是IRP:

I/O request packets,简称IRP。即输入输出请求包。它是WINDOWS内核中的一种非常重要的数据结构。上层应用程序与底层驱动程序通信时,应用程序会发出I/O请求。操作系统将相应的I/O请求转换为相应的IRP。不同的IRP会根据类型被分派的不同的派遣历程中进行处理。

作用:

上层应用程序于底层驱动之间的通讯,即EXE程序和SYS之间的通讯。
应用程序 想要访问内核数据,必须通过IRP数据。又叫IRP请求,当应用程序和驱动交互时,发送一个IRP请求,IRP会在各层设备驱动个之间来回传动和转发。

五种常用的IRP类型:

#define IRP_MJ_CREATE 0X00 //对应用户层函数CreateFile()
#define IRP_MJ_CLOSE  0X02 //对应用户层函数CloseHandle()
#define IRP_MJ_READ 0X03 //对应用户层函数ReadFile()
#define IRP_MJ_WRITE 0X04 //对应用户层函数WirteFile()
#define IRP_MJ_DEVICE_CONTROL 0X0e //DeviceIoControl()

使用过程:

  1. 创建IRP处理函数。
  2. 在驱动入口函数里面DriverEntry()注册处理函数。
  3. 细化IRP函数。

(1)注册派遣函数
在这里插入图片描述
在这里插入图片描述
(2)应用程序与驱动通信
在驱动里创建符号链接
在这里插入图片描述
通过符号链接与相应驱动程序通信
在这里插入图片描述
IRP 是数据请求包的一个简称。当应用程序发起CreateFile或ReadFile API操作设备的时候,就会将相关参数信息封装为一个IRP数据包。通过IoCallDriver传递给驱动程序。

IRP数据结构

typedef struct _IRP {
    PMDL              MdlAddress;
    ULONG             Flags;
    union {
        struct _IRP*   MasterIrp;
        PVOID          SystemBuffer;
    } AssociatedIrp;
    IO_STATUS_BLOCK   IoStatus;
    KPROCESSOR_MODE   RequestorMode;
    BOOLEAN           PendingReturned;
    BOOLEAN           Cancel;
    KIRQL             CancelIrql;
    PDRIVER_CANCEL    CancelRoutine;
    PVOID             UserBuffer;
    union {
        struct {
            union {
                KDEVICE_QUEUE_ENTRY DeviceQueueEntry;
                struct {
                    PVOID    DriverContext[4];
                };
            };
            PETHREAD     Thread;
            LIST_ENTRY   ListEntry;
        } Overlay;
    } Tail;
} IRP, *PIRP;


kd> dt nt!_IRP
   +0x000 Type             : Int2B
   +0x002 Size             : Uint2B
   +0x004 MdlAddress       : Ptr32 _MDL
   +0x008 Flags            : Uint4B
   +0x00c AssociatedIrp    : <unnamed-tag>
   +0x010 ThreadListEntry  : _LIST_ENTRY
   +0x018 IoStatus         : _IO_STATUS_BLOCK
   +0x020 RequestorMode    : Char
   +0x021 PendingReturned  : UChar
   +0x022 StackCount       : Char
   +0x023 CurrentLocation  : Char
   +0x024 Cancel           : UChar
   +0x025 CancelIrql       : UChar
   +0x026 ApcEnvironment   : Char
   +0x027 AllocationFlags  : UChar
   +0x028 UserIosb         : Ptr32 _IO_STATUS_BLOCK
   +0x02c UserEvent        : Ptr32 _KEVENT
   +0x030 Overlay          : <unnamed-tag>
   +0x038 CancelRoutine    : Ptr32     void 
   +0x03c UserBuffer       : Ptr32 Void
   +0x040 Tail             : <unnamed-tag>

具体含义:

MdlAddress : 是一个MDL的指针,当内核层和用户层采用共享内存的结构传递数据的时候,这个MDL就代表共享的内存信息(共享物理内存,通过MDL映射)。这个成员生效的标记为:DO_DIRECT_IO, METHOD_IN_DIRECT 或者METHOD_OUT_DIRECT.
AssociatedIrp : 这个成员是个联合体,其中存在一个SystemBuffer程序;当内核层使用用户层的数据的时候是通过拷贝数据的方式来实现的话,那么拷贝后的数据就放在了AssociatedIrp.SystemBuffer中了。这个成员生效的标记是DO_BUFFERED_IO或者METHOD_BUFFERED。
IoStatus : 返回的状态信息。
RequestorMode : UserMode或KernelMode,指定原始I/O请求的来源。驱动程序有时需要查看这个值来决定是否要信任某些参数。
PendingReturned : Pending 状态,如果为TRUE,则表明处理该IRP的最低级派遣例程返回了STATUS_PENDING。
StackCount : 设备栈的数目。
CurrentLocation : 当前处于哪个设备栈的索引。
Cancel : IRP是否被取消,如果为TRUE,则表明IoCancelIrp已被调用(该函数用于取消这个请求)。如果为FALSE,则表明没有调用IoCancelIrp函数。
CancelIrql(KIRQL) : 是一个IRQL值,表明那个专用的取消自旋锁是在这个IRQL上获取的.
CancelRoutine(PDRIVER_CANCEL) : 是驱动程序取消例程的地址。你应该使用IoSetCancelRoutine函数设置这个域而不是直接修改该域(因为可以原子修改)。
UserBuffer(PVOID) : 用户层参数的直接地址,设置标记METHOD_NEITHER时候有效。
Tail.Overlay 是Tail联合中的一种联合结构,如下:

图示

在这里插入图片描述
应用程序和驱动:
在这里插入图片描述
在这里插入图片描述
Windows驱动大致分为:
function driver: 设备功能驱动
filter driver: 设备辅助驱动
software driver: 软件模块驱动
bus driver: 总线设备驱动

驱动程序通信:

https://github.com/G4rb3n/Windows-Driver/tree/master/MT-Communication

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值