A Driver Object has the Following structure.
typedef struct _DRIVER_OBJECT
{
SHORT Type;
SHORT 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;
LONG * DriverInit;
PVOID DriverStartIo;
PVOID DriverUnload;
LONG * MajorFunction[28];
} DRIVER_OBJECT, *PDRIVER_OBJECT;
Looking at a driver in DeviceTree utility
Following is the Driver related to keyboard
Using Windbg we can see the Structure of the Driver.
kd> !drvobj kbdclassDriver object (8186aae8) is for:\Driver\KbdclassDriver Extension List: (id , addr)Device Object list:81798a58 81864860
Lets see the DevObject at 81864860
kd> !devobj 81864860Device object (81864860) is for:KeyboardClass0 \Driver\Kbdclass DriverObject 8186aae8Current Irp 00000000 RefCount 1 Type 0000000b Flags 00002044
Now lets see the DriverObject at 8186aae8 which is KeyboardClass0
kd> !drvobj 8186AAE8 7Driver object (8186aae8) is for:\Driver\KbdclassDriver Extension List: (id , addr)Device Object list:81798a58 81864860DriverEntry: f9cb0610DriverStartIo: 00000000DriverUnload: 00000000AddDevice: f9cafb02Dispatch routines:[00] IRP_MJ_CREATE f9cacdd8 +0xf9cacdd8[01] IRP_MJ_CREATE_NAMED_PIPE 804f320e nt!IopInvalidDeviceRequest[02] IRP_MJ_CLOSE f9cacfe8 +0xf9cacfe8[03] IRP_MJ_READ f9cadc82 +0xf9cadc82[04] IRP_MJ_WRITE 804f320e nt!IopInvalidDeviceRequest[05] IRP_MJ_QUERY_INFORMATION 804f320e nt!IopInvalidDeviceRequest[06] IRP_MJ_SET_INFORMATION 804f320e nt!IopInvalidDeviceRequest[07] IRP_MJ_QUERY_EA 804f320e nt!IopInvalidDeviceRequest[08] IRP_MJ_SET_EA 804f320e nt!IopInvalidDeviceRequest[09] IRP_MJ_FLUSH_BUFFERS f9cacd50 +0xf9cacd50[0a] IRP_MJ_QUERY_VOLUME_INFORMATION 804f320e nt!IopInvalidDeviceRequest[0b] IRP_MJ_SET_VOLUME_INFORMATION 804f320e nt!IopInvalidDeviceRequest[0c] IRP_MJ_DIRECTORY_CONTROL 804f320e nt!IopInvalidDeviceRequest[0d] IRP_MJ_FILE_SYSTEM_CONTROL 804f320e nt!IopInvalidDeviceRequest[0e] IRP_MJ_DEVICE_CONTROL f9caea44 +0xf9caea44[0f] IRP_MJ_INTERNAL_DEVICE_CONTROL f9cae386 +0xf9cae386[10] IRP_MJ_SHUTDOWN 804f320e nt!IopInvalidDeviceRequest[11] IRP_MJ_LOCK_CONTROL 804f320e nt!IopInvalidDeviceRequest[12] IRP_MJ_CLEANUP f9cacd0c +0xf9cacd0c[13] IRP_MJ_CREATE_MAILSLOT 804f320e nt!IopInvalidDeviceRequest[14] IRP_MJ_QUERY_SECURITY 804f320e nt!IopInvalidDeviceRequest[15] IRP_MJ_SET_SECURITY 804f320e nt!IopInvalidDeviceRequest[16] IRP_MJ_POWER f9caf196 +0xf9caf196[17] IRP_MJ_SYSTEM_CONTROL f9cae844 +0xf9cae844[18] IRP_MJ_DEVICE_CHANGE 804f320e nt!IopInvalidDeviceRequest[19] IRP_MJ_QUERY_QUOTA 804f320e nt!IopInvalidDeviceRequest[1a] IRP_MJ_SET_QUOTA 804f320e nt!IopInvalidDeviceRequest[1b] IRP_MJ_PNP f9cad798 +0xf9cad798
Now lets write a kernel mode driver code to do the same thing
/*
kd> !drvobj kbdclassDriver object (8186aae8) is for:\Driver\KbdclassDriver Extension List: (id , addr)Device Object list:81798a58 81864860kd> !devobj 81864860Device object (81864860) is for:KeyboardClass0 \Driver\Kbdclass DriverObject 8186aae8Current Irp 00000000 RefCount 1 Type 0000000b Flags 00002044Dacl e13ae02c DevExt 81864918 DevObjExt 818649f8ExtensionFlags (0000000000)AttachedTo (Lower) 81864a58*** ERROR: Module load completed but symbols could not be loaded for nmfilter.sys\Driver\nmfilterDevice queue is not busy.kd> !drvobj 8186AAE8Driver object (8186aae8) is for:\Driver\KbdclassDriver Extension List: (id , addr)Device Object list:81798a58 81864860//out of the codeaddr of drivr=8186AAE8addr of device =81798A58addr of irp =F9CACDD8*/#include <ntddk.h>VOID DriverUnload(IN PDRIVER_OBJECT DriverObject);NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath){PDRIVER_OBJECT drvcopy;PDEVICE_OBJECT devcopy;UNICODE_STRING DeviceName;PDEVICE_OBJECT device;PFILE_OBJECT file;NTSTATUS s;DbgPrint("driver 7\n");//variables should be declared beforeRtlInitUnicodeString(&DeviceName,L"\\Device\\KeyboardClass0");s = IoGetDeviceObjectPointer(&DeviceName,FILE_ALL_ACCESS,&file,&device);if (!NT_SUCCESS(s)){DbgPrint("Get Device error!");return s;}drvcopy = device->DriverObject;//device is pointerDbgPrint("addr of driver=%p \n",drvcopy);devcopy = drvcopy->DeviceObject;DbgPrint("addr of device =%p \n",devcopy);DbgPrint("addr of irp =%p \n",drvcopy->MajorFunction[IRP_MJ_CREATE] );DriverObject->DriverUnload = DriverUnload;return STATUS_SUCCESS;}VOID DriverUnload(IN PDRIVER_OBJECT DriverObject){DbgPrint("Driver Unload! \n");}
We can see the output in DebugView
Well “addr of irp” in the figure is address IRP_MJ_CREATE