-
-
[原创]关键对象
-
发表于: 2024-8-15 10:58 1697
-
关键对象
Most Important
内核中,一个内核程序用一个驱动对象来表示(DRIVER_OBJECT)一个.sys文件可以产生多个驱动对象,第一个驱动对象由操作系统产生,其后也可以写代码自行创建,而一个驱动对象产生多个设备对象(用IoCreateDevice来创建设备对象DEVICE_OBJECT)。而只有设备对象,能相应请求(IRP,来自上层的请求与通信)。设备对象与实际“硬件”绑定。
驱动对象
在 Windows 操作系统中,驱动对象(Driver Object)是内核模式下的一个数据结构,它表示一个加载到内核中的驱动程序。驱动对象由操作系统创建并传递给驱动程序的初始化例程(如
DriverEntry
),它包含驱动程序的相关信息和函数指针,用于处理 I/O 请求和管理设备。驱动对象的作用
驱动对象在驱动程序和操作系统之间起着桥梁作用,主要有以下几个作用:
- 维护驱动程序的状态信息:驱动对象包含指向设备对象的指针列表、驱动程序的入口点、卸载例程等。
- 处理 I/O 请求:驱动对象包含函数指针,用于处理各种 I/O 请求,如创建、关闭、读、写、设备控制等。
- 管理设备:驱动对象包含设备对象列表,表示驱动程序管理的所有设备实例。
驱动对象的结构
驱动对象是一个
DRIVER_OBJECT
结构,定义在ntddk.h
中,主要字段包括:DriverSize
:驱动对象的大小。DriverExtension
:指向驱动对象扩展的指针。DeviceObject
:指向驱动程序管理的设备对象链表的指针。DriverStart
:驱动程序映像的起始地址。DriverUnload
:指向驱动程序卸载例程的指针。MajorFunction
:指向驱动程序处理 I/O 请求的调度例程的指针数组。
驱动对象的创建和使用
驱动对象由操作系统在加载驱动程序时创建,并传递给驱动程序的入口点例程(如
DriverEntry
)。设备对象
在Windows操作系统中,设备对象(Device Object)是内核模式下的一个数据结构,它代表操作系统中的设备。设备对象可以是与实际硬件设备关联的,也可以是与虚拟设备或软件设备关联的。
设备对象的作用
设备对象在驱动程序和操作系统之间起着桥梁作用,负责处理I/O请求和管理设备状态。它包含设备相关的信息和函数指针,用于处理I/O操作。
设备对象的类型
设备对象可以分为以下几种类型:
- 物理设备对象(Physical Device Object,PDO):
- 代表实际的硬件设备。通常由总线驱动程序(如PCI、USB驱动程序)创建。
- 每个物理设备对象都与硬件设备的一个实例相对应。
- 功能设备对象(Functional Device Object,FDO):
- 代表驱动程序管理的设备功能。通常由功能驱动程序创建。
- 功能设备对象处理设备的主要功能,如读写操作、控制命令等。
- 筛选设备对象(Filter Device Object,Filter DO):
- 用于过滤或修改I/O请求。通常由筛选驱动程序创建。
- 筛选设备对象位于设备堆栈中,能够在请求到达功能设备对象之前对其进行处理或修改。
设备对象和实际硬件设备的关系
- 绑定实际硬件设备:物理设备对象(PDO)通常绑定到实际的硬件设备,每个硬件设备在系统中都有一个对应的PDO。总线驱动程序检测到设备后,会创建PDO并报告给操作系统。
- 虚拟设备或软件设备:功能设备对象(FDO)和筛选设备对象(Filter DO)可以绑定到实际硬件设备,也可以绑定到虚拟设备或纯软件设备。例如,虚拟磁盘驱动程序可能会创建一个设备对象,代表一个由软件模拟的磁盘。
- 物理设备对象(Physical Device Object,PDO):
请求
在 Windows 操作系统的内核模式编程中,I/O 请求数据包(IRP,I/O Request Packet)是用于描述 I/O 操作的结构体。IRP 是驱动程序与操作系统和设备之间进行通信的核心机制。每个 IRP 表示一个 I/O 操作请求,例如读、写、设备控制等。
IRP 的结构
IRP 结构体包含描述 I/O 请求的所有必要信息,包括目标设备、请求的类型、请求的参数、状态等。IRP 的定义在头文件
ntddk.h
中。IRP 结构体的主要字段包括:Type
: IRP 类型。Size
: IRP 结构体的大小。MdlAddress
: 指向内存描述列表(MDL)的指针,用于描述与 I/O 操作相关的内存缓冲区。Flags
: IRP 的标志。AssociatedIrp
: 与当前 IRP 关联的 IRP 信息。ThreadListEntry
: IRP 的线程列表条目。IoStatus
: 描述 I/O 操作的状态和信息。RequestorMode
: 请求者的模式(内核模式或用户模式)。PendingReturned
: 指示 IRP 是否处于挂起状态。Cancel
: 指示 IRP 是否已取消。CancelIrql
: 取消 IRP 时的 IRQL 值。CancelRoutine
: 指向取消例程的指针。UserIosb
: 指向用户 I/O 状态块的指针。UserEvent
: 指向用户事件的指针。Overlay
: 覆盖结构体,用于保存与 I/O 请求相关的其他信息。
IRP 的生命周期
- 创建:当应用程序或操作系统需要进行 I/O 操作时,会创建一个 IRP,并将其发送给相应的驱动程序。
- 处理:驱动程序收到 IRP 后,会根据 IRP 中的信息进行相应的处理。例如,如果是读请求,驱动程序会从设备读取数据并将其填入缓冲区。
- 完成:当 I/O 操作完成后,驱动程序会设置 IRP 的状态并调用
IoCompleteRequest
函数完成 IRP。操作系统会将结果返回给请求者。
IRP 的处理
驱动程序通过调度例程(Dispatch Routine)来处理不同类型的 IRP。调度例程是驱动对象中的一个函数指针数组,驱动程序可以根据 IRP 的主要功能代码(Major Function Code)选择相应的处理函数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | typedef struct _DRIVER_OBJECT { CSHORT Type; //结构的类型 CSHORT Size; //结构的大小 PDEVICE_OBJECT DeviceObject; //该驱动下设备对象链表的开始 ULONG Flags; PVOID DriverStart; //该内核模块在内核中的开始地址 ULONG DriverSize; //该内核模块在内核中的大小 PVOID DriverSection; PDRIVER_EXTENSION DriverExtension; UNICODE_STRING DriverName; //驱动的名字 PUNICODE_STRING HardwareDatabase; PFAST_IO_DISPATCH FastIoDispatch; //快速IO分发 PDRIVER_INITIALIZE DriverInit; PDRIVER_STARTIO DriverStartIo; PDRIVER_UNLOAD DriverUnload; //驱动卸载函数 PDRIVER_DISPATCH MajorFunction[IRP_MJ_MAXIMUM_FUNCTION + 1]; //普通分发函数 } DRIVER_OBJECT, *PDRIVER_OBJECT; |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | typedef struct _DEVICE_OBJECT { CSHORT Type; //结构的类型 USHORT Size; //结构的大小 LONG ReferenceCount; //引用计数 struct _DRIVER_OBJECT *DriverObject; //指向设备所属的驱动对象 struct _DEVICE_OBJECT *NextDevice; //设备对象单项链表 struct _DEVICE_OBJECT *AttachedDevice; struct _IRP *CurrentIrp; PIO_TIMER Timer; ULONG Flags; ULONG Characteristics; __volatile PVPB Vpb; PVOID DeviceExtension; DEVICE_TYPE DeviceType; //设备的类型 CCHAR StackSize; //IRP栈大小 union { LIST_ENTRY ListEntry; WAIT_CONTEXT_BLOCK Wcb; } Queue; ULONG AlignmentRequirement; KDEVICE_QUEUE DeviceQueue; KDPC Dpc; ULONG ActiveThreadCount; PSECURITY_DESCRIPTOR SecurityDescriptor; KEVENT DeviceLock; USHORT SectorSize; USHORT Spare1; struct _DEVOBJ_EXTENSION *DeviceObjectExtension; PVOID Reserved; } DEVICE_OBJECT, *PDEVICE_OBJECT; |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | typedef struct _IRP { CSHORT Type; USHORT Size; PMDL MdlAddress; ULONG Flags; union { struct _IRP *MasterIrp; __volatile LONG IrpCount; PVOID SystemBuffer; } AssociatedIrp; LIST_ENTRY ThreadListEntry; IO_STATUS_BLOCK IoStatus; KPROCESSOR_MODE RequestorMode; BOOLEAN PendingReturned; CHAR StackCount; CHAR CurrentLocation; BOOLEAN Cancel; KIRQL CancelIrql; CCHAR ApcEnvironment; UCHAR AllocationFlags; union { PIO_STATUS_BLOCK UserIosb; PVOID IoRingContext; }; PKEVENT UserEvent; union { struct { union { PIO_APC_ROUTINE UserApcRoutine; PVOID IssuingProcess; }; union { PVOID UserApcContext; #if ... _IORING_OBJECT *IoRing; #else struct _IORING_OBJECT *IoRing; #endif }; } AsynchronousParameters; LARGE_INTEGER AllocationSize; } Overlay; __volatile PDRIVER_CANCEL CancelRoutine; PVOID UserBuffer; union { struct { union { KDEVICE_QUEUE_ENTRY DeviceQueueEntry; struct { PVOID DriverContext[4]; }; }; PETHREAD Thread; PCHAR AuxiliaryBuffer; struct { LIST_ENTRY ListEntry; union { struct _IO_STACK_LOCATION *CurrentStackLocation; ULONG PacketType; }; }; PFILE_OBJECT OriginalFileObject; } Overlay; KAPC Apc; PVOID CompletionKey; } Tail; } IRP; |