首页
社区
课程
招聘
[原创]关键对象
发表于: 2024-8-15 10:58 1662

[原创]关键对象

2024-8-15 10:58
1662

关键对象

Most Important

内核中,一个内核程序用一个驱动对象来表示(DRIVER_OBJECT)一个.sys文件可以产生多个驱动对象,第一个驱动对象由操作系统产生,其后也可以写代码自行创建,而一个驱动对象产生多个设备对象(用IoCreateDevice来创建设备对象DEVICE_OBJECT)。而只有设备对象,能相应请求(IRP,来自上层的请求与通信)。设备对象与实际“硬件”绑定。

  • 驱动对象

    在 Windows 操作系统中,驱动对象(Driver Object)是内核模式下的一个数据结构,它表示一个加载到内核中的驱动程序。驱动对象由操作系统创建并传递给驱动程序的初始化例程(如 DriverEntry),它包含驱动程序的相关信息和函数指针,用于处理 I/O 请求和管理设备。

    驱动对象的作用

    驱动对象在驱动程序和操作系统之间起着桥梁作用,主要有以下几个作用:

    1. 维护驱动程序的状态信息:驱动对象包含指向设备对象的指针列表、驱动程序的入口点、卸载例程等。
    2. 处理 I/O 请求:驱动对象包含函数指针,用于处理各种 I/O 请求,如创建、关闭、读、写、设备控制等。
    3. 管理设备:驱动对象包含设备对象列表,表示驱动程序管理的所有设备实例。

    驱动对象的结构

    驱动对象是一个 DRIVER_OBJECT 结构,定义在 ntddk.h 中,主要字段包括:

    • DriverSize:驱动对象的大小。
    • DriverExtension:指向驱动对象扩展的指针。
    • DeviceObject:指向驱动程序管理的设备对象链表的指针。
    • DriverStart:驱动程序映像的起始地址。
    • DriverUnload:指向驱动程序卸载例程的指针。
    • MajorFunction:指向驱动程序处理 I/O 请求的调度例程的指针数组。

    驱动对象的创建和使用

    驱动对象由操作系统在加载驱动程序时创建,并传递给驱动程序的入口点例程(如 DriverEntry)。

  • 设备对象

    在Windows操作系统中,设备对象(Device Object)是内核模式下的一个数据结构,它代表操作系统中的设备。设备对象可以是与实际硬件设备关联的,也可以是与虚拟设备或软件设备关联的。

    设备对象的作用

    设备对象在驱动程序和操作系统之间起着桥梁作用,负责处理I/O请求和管理设备状态。它包含设备相关的信息和函数指针,用于处理I/O操作。

    设备对象的类型

    设备对象可以分为以下几种类型:

    1. 物理设备对象(Physical Device Object,PDO)
      • 代表实际的硬件设备。通常由总线驱动程序(如PCI、USB驱动程序)创建。
      • 每个物理设备对象都与硬件设备的一个实例相对应。
    2. 功能设备对象(Functional Device Object,FDO)
      • 代表驱动程序管理的设备功能。通常由功能驱动程序创建。
      • 功能设备对象处理设备的主要功能,如读写操作、控制命令等。
    3. 筛选设备对象(Filter Device Object,Filter DO)
      • 用于过滤或修改I/O请求。通常由筛选驱动程序创建。
      • 筛选设备对象位于设备堆栈中,能够在请求到达功能设备对象之前对其进行处理或修改。

    设备对象和实际硬件设备的关系

    • 绑定实际硬件设备:物理设备对象(PDO)通常绑定到实际的硬件设备,每个硬件设备在系统中都有一个对应的PDO。总线驱动程序检测到设备后,会创建PDO并报告给操作系统。
    • 虚拟设备或软件设备:功能设备对象(FDO)和筛选设备对象(Filter DO)可以绑定到实际硬件设备,也可以绑定到虚拟设备或纯软件设备。例如,虚拟磁盘驱动程序可能会创建一个设备对象,代表一个由软件模拟的磁盘。
  • 请求

    在 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 的生命周期

    1. 创建:当应用程序或操作系统需要进行 I/O 操作时,会创建一个 IRP,并将其发送给相应的驱动程序。
    2. 处理:驱动程序收到 IRP 后,会根据 IRP 中的信息进行相应的处理。例如,如果是读请求,驱动程序会从设备读取数据并将其填入缓冲区。
    3. 完成:当 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;


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//