-
Notifications
You must be signed in to change notification settings - Fork 96
Driver Objects
Each loaded driver is represented by a kernel object of Driver type. The structure of the object body is defined as DRIVER_OBJECT
and you can see it below. This chapter describes its members that are interesting in the IRPMon context. The most interesting structure fields in that aspect are printed in bold.
Listing 1: The DRIVER_OBJECT
structure
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;
PDRIVER_INITIALIZE DriverInit;
PDRIVER_STARTIO DriverStartIo;
PDRIVER_UNLOAD DriverUnload;
PDRIVER_DISPATCH MajorFunction[0x1C];
} DRIVER_OBJECT;
As said in Drivers and Devices chapter, each device is associated with one driver. This fact can also be viewed from the driver perspective: each driver own none, one or multiple devices. The devices owned by one driver are stored in a singly linked list and address of its first item (first device) is stored inside the DeviceObject
member of the driver object body. Each device, described by the DEVICE_OBJECT
, contains a pointer to the next device in the list (the NextDevice
filed of the device object body).
DriverStart
and DriverSize
members describe position of the driver image in memory: its base address and size in bytes.
Address of the DriverEntry routine is stored within the DriverInit
field. The routine is invoked just after the driver image is mapped to kernel memory and it is responsible for the whole driver initialization. If a driver can be dynamically unloaded, it sets the DriverUnload
field to point to its unload routine, which is invoked just before unmapping the driver image from memory. If the driver does not set its unload routine (DriverUnload
is NULL
) the driver cannot be unloaded from the system without a reboot.
The MajorFunction
array defines all callback routines responsible for handling IRPs. When sending a request to driver's device, the kernel selects appropriate callback routine from the array by using the major type of the request as an index. All the callbacks stored in the MajorFunction
array has the same signature named DRIVER_DISPATCH
showed in Listing 2. The callbacks accept two arguments, the device object to which the request just arrived, and the request itself. They return a NTSTATUS value indicating whether the request was completed and how successfully the driver handled it.
Listing 2: Signature of the callback routines responsible for handling IRPs
typedef NTSTATUS (NTAPI DRIVER_DISPATCH)(
PDEVICE_OBJECT DeviceObject,
PIRP Irp);`
Driver's StartIo can be used to serialize request targeted at certain device or driver. Its signature reflects the DRIVER_DISPATCH
type, however, there are some differences from callbacks stored inside the MajorFunction
array:
- there may be at most one StartIo routine defined per driver, thus serving all types of requests,
- the routine handles only requests passed to it by the owning driver,
- the routine does not support device stacks or any other type of layering
- the routine is optional, the driver can decide not to define any. When a driver decides not to define one of its IRP callbacks, the callback points to a default handler inside the kernel, called IopInvalidDeviceRequest.
If a driver decides to support also fast I/O method of communication (which is completely optional unless the driver is a file system or file system filter), the DriverEntry routine allocates a FAST_IO_DISPATCH
structure and stores its address in the FastIoDispatch
field of its driver object structure. The FAST_IO_DISPATCH
structure consists of various callbacks with various signatures. The callbacks are invoked at various times and places. If the driver does not support fast I/O, it just leaves the FastIoDispatch
field as is.
When a driver supports Plug&Play (PnP), it needs to be informed when a device of interesting type is connected to the computer (either physically or virtually). This purpose is served by the AddDevice routine which is stored in an extension of the driver object (address of the extension is stored in the DriverExtension
field). Definition of the driver extension structure and signature of the AddDevice routine are described in Listing 3.
Listing 3: Structure of the driver extension and signature of the AddDevice routine
typedef NTSTATUS (DRIVER_ADD_DEVICE) (
struct _DRIVER_OBJECT *DriverObject,
struct _DEVICE_OBJECT *PhysicalDeviceObject);
typedef struct _DRIVER_EXTENSION {
struct _DRIVER_OBJECT *DriverObject;
PDRIVER_ADD_DEVICE AddDevice;
ULONG Count;
UNICODE_STRING ServiceKeyName;
} DRIVER_EXTENSION, *PDRIVER_EXTENSION;
When the kernel considers a driver is worth of being informed about arrival of a new device, it invokes its AddDevice routine. If the driver is not loaded in memory, the kernel does so and does not forget to initialize the driver via its DriverEntry. The kernel passes the following parameters to the AddDevice routine:
-
DriverObject
. Address of the driver object representing the driver. -
PhysicalDeviceObject
. Address of the bottom device object in the device stack representing the newly arrived device.
If driver's AddDevice routine considers the newly arrived device interesting enough, it usually creates a new device object and attaches it to the top of the stack, making the driver able of monitoring and filtering all IRPs going to the new device.
A driver may define its AddDevice routine during its DriverEntry by setting the AddDevice
member of its driver extension structure. Drivers that have AddDevice routine are sometimes called Plug&Play drivers (PnP drivers).
- IRPMonDllClassWatchEnum
- IRPMonDllClassWatchEnumFree
- IRPMonDllClassWatchRegister
- IRPMonDllClassWatchUnregister
- IRPMonDllCloseHookedDeviceHandle
- IRPMonDllCloseHookedDriverHandle
- IRPMonDllConnect
- IRPMonDllDisconnect
- IRPMonDllDriverHooksEnumerate
- IRPMonDllDriverHooksFree
- IRPMonDllDriverNameWatchEnum
- IRPMonDllDriverNameWatchEnumFree
- IRPMonDllDriverNameWatchRegister
- IRPMonDllDriverNameWatchUnregister
- IRPMonDllDriverSetInfo
- IRPMonDllDriverStartMonitoring
- IRPMonDllDriverStopMonitoring
- IRPMonDllEmulateDriverDevices
- IRPMonDllEmulateProcesses
- IRPMonDllFinalize
- IRPMonDllGetRequest
- IRPMonDllHookDeviceByAddress
- IRPMonDllHookDeviceByName
- IRPMonDllHookDriver
- IRPMonDllHookedDeviceGetInfo
- IRPMonDllHookedDeviceSetInfo
- IRPMonDllHookedDriverGetInfo
- IRPMonDllInitialize
- IRPMonDllInitialized
- IRPMonDllOpenHookedDevice
- IRPMonDllOpenHookedDriver
- IRPMonDllQueueClear
- IRPMonDllSettingsQuery
- IRPMonDllSettingsSet
- IRPMonDllSnapshotFree
- IRPMonDllSnapshotRetrieve
- IRPMonDllUnhookDevice
- IRPMonDllUnhookDriver
- CLASS_WATCH_RECORD
- DRIVER_MONITOR_SETTINGS
- DRIVER_NAME_WATCH_RECORD
- EFastIoOperationType
- EIRPMonConnectorType
- ERequestHeaderFlags
- ERequestResultType
- ERequestType
- HOOKED_DEVICE_INFO
- HOOKED_DEVICE_UMINFO
- HOOKED_DRIVER_INFO
- HOOKED_DRIVER_UMINFO
- HOOKED_OBJECTS_INFO
- IRPMNDRV_SETTINGS
- IRPMON_DEVICE_INFO
- IRPMON_DEVICE_INIT_INFO
- IRPMON_DRIVER_INFO
- IRPMON_INIT_INFO
- IRPMON_INIT_INFO_DATA
- IRPMON_NETWORK_INIT_INFO
- PCLASS_WATCH_RECORD
- PDRIVER_MONITOR_SETTINGS
- PDRIVER_NAME_WATCH_RECORD
- PEFastIoOperationType
- PEIRPMonConnectorType
- PERequestHeaderFlags
- PERequestResultType
- PERequestType
- PHOOKED_DEVICE_INFO
- PHOOKED_DEVICE_UMINFO
- PHOOKED_DRIVER_INFO
- PHOOKED_DRIVER_UMINFO
- PHOOKED_OBJECTS_INFO
- PIRPMNDRV_SETTINGS
- PIRPMON_DEVICE_INFO
- PIRPMON_DEVICE_INIT_INFO
- PIRPMON_DRIVER_INFO
- PIRPMON_INIT_INFO
- PIRPMON_INIT_INFO_DATA
- PIRPMON_NETWORK_INIT_INFO
- PREQUEST_ADDDEVICE
- PREQUEST_FASTIO
- PREQUEST_HEADER
- PREQUEST_IRP
- PREQUEST_STARTIO
- PREQUEST_UNLOAD
- REQUEST_ADDDEVICE
- REQUEST_FASTIO
- REQUEST_HEADER
- REQUEST_IRP
- REQUEST_STARTIO
- REQUEST_UNLOAD
- _CLASS_WATCH_RECORD
- _DRIVER_MONITOR_SETTINGS
- _DRIVER_NAME_WATCH_RECORD
- _EFastIoOperationType
- _EIRPMonConnectorType
- _ERequestHeaderFlags
- _ERequestResultType
- _ERequestType
- _HOOKED_DEVICE_INFO
- _HOOKED_DEVICE_UMINFO
- _HOOKED_DRIVER_INFO
- _HOOKED_DRIVER_UMINFO
- _HOOKED_OBJECTS_INFO
- _IRPMNDRV_SETTINGS
- _IRPMON_DEVICE_INFO
- _IRPMON_DEVICE_INIT_INFO
- _IRPMON_DRIVER_INFO
- _IRPMON_INIT_INFO
- _IRPMON_INIT_INFO_DATA
- _IRPMON_NETWORK_INIT_INFO
- _REQUEST_ADDDEVICE
- _REQUEST_FASTIO
- _REQUEST_HEADER
- _REQUEST_IRP
- _REQUEST_STARTIO
- _REQUEST_UNLOAD