我们知道每个驱动程序都有一个入口点
NTSTATUS DriverEntry(
IN OUT PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
);
那么我们就会疑惑 DriverObject 这个到底是个什么东西
kd> dt _DRIVER_OBJECT
nt!_DRIVER_OBJECT
+0x000 Type : Int2B
+0x002 Size : Int2B
+0x004 DeviceObject : Ptr32 _DEVICE_OBJECT //设备对象
+0x008 Flags : Uint4B
+0x00c DriverStart : Ptr32 Void
+0x010 DriverSize : Uint4B
+0x014 DriverSection : Ptr32 Void
+0x018 DriverExtension : Ptr32 _DRIVER_EXTENSION
+0x01c DriverName : _UNICODE_STRING
+0x024 HardwareDatabase : Ptr32 _UNICODE_STRING
+0x028 FastIoDispatch : Ptr32 _FAST_IO_DISPATCH
+0x02c DriverInit : Ptr32 long
+0x030 DriverStartIo : Ptr32 void
+0x034 DriverUnload : Ptr32 void
+0x038 MajorFunction : [28] Ptr32 long
我们看到这个结构体说明了这个驱动的类型 大小 对应的设备 驱动的入口点 大小 SECTION 名字
kd> dt PDRIVER_OBJECT f8af1c84
Major!PDRIVER_OBJECT
0x81fa6da0
+0x000 Type : 0n4
+0x002 Size : 0n168
+0x004 DeviceObject : (null)
+0x008 Flags : 2
+0x00c DriverStart : 0xf899a000 Void
+0x010 DriverSize : 0x7000
+0x014 DriverSection : 0x81fddef8 Void
+0x018 DriverExtension : 0x81fa6e48 _DRIVER_EXTENSION
+0x01c DriverName : _UNICODE_STRING "\Driver\Major.sys"
+0x024 HardwareDatabase : 0x80671ae0 _UNICODE_STRING "\REGISTRY\MACHINE\HARDWARE\DESCRIPTION\SYSTEM"
+0x028 FastIoDispatch : (null)
+0x02c DriverInit : 0xf899e03e long Major!GsDriverEntry+0
+0x030 DriverStartIo : (null)
+0x034 DriverUnload : (null)
+0x038 MajorFunction : [28] 0x804f454a long nt!IopInvalidDeviceRequest+0
因为因为我们的驱动没有对应的设备 所以 +0x004 DeviceObject : (null)
入口点为 +0x00c DriverStart : 0xf899a000 Void
来看下对不对
Major!DriverEntry+0x8:
f899b168 cc int 3
我们定义的INT3断点 中断地址是 f899b168 cc 这里我们可以看到在驱动入口之前应该还有很多其他的代码 (干什么用的就不是很清楚了)
这个结构体中有驱动的名字 驱动的开始地址等信息
来看PUNICODE_STRING
kd> dt PUNICODE_STRING
Major!PUNICODE_STRING
Ptr32 +0x000 Length : Uint2B //长度
+0x002 MaximumLength : Uint2B //最长长度
+0x004 Buffer : Ptr32 Uint2B //数据(unicode)
可以看到REGISTERPATH 中是我们驱动在注册表的位置
.....
接下来我们就要创建一个设备对象 创建这个设备对象主要是为了与3环通讯
kd> dt PDEVICE_OBJECT
Major!PDEVICE_OBJECT
Ptr32 +0x000 Type : Int2B
+0x002 Size : Uint2B
+0x004 ReferenceCount : Int4B
+0x008 DriverObject : Ptr32 _DRIVER_OBJECT
+0x00c NextDevice : Ptr32 _DEVICE_OBJECT
+0x010 AttachedDevice : Ptr32 _DEVICE_OBJECT
+0x014 CurrentIrp : Ptr32 _IRP
+0x018 Timer : Ptr32 _IO_TIMER
+0x01c Flags : Uint4B
+0x020 Characteristics : Uint4B
+0x024 Vpb : Ptr32 _VPB
+0x028 DeviceExtension : Ptr32 Void
+0x02c DeviceType : Uint4B
+0x030 StackSize : Char
+0x034 Queue : <unnamed-tag>
+0x05c AlignmentRequirement : Uint4B
+0x060 DeviceQueue : _KDEVICE_QUEUE
+0x074 Dpc : _KDPC
+0x094 ActiveThreadCount : Uint4B
+0x098 SecurityDescriptor : Ptr32 Void
+0x09c DeviceLock : _KEVENT
+0x0ac SectorSize : Uint2B
+0x0ae Spare1 : Uint2B
+0x0b0 DeviceObjectExtension : Ptr32 _DEVOBJ_EXTENSION
+0x0b4 Reserved : Ptr32 Void
当我们创建完对设备象后(IoCreateDevice)
kd> dt PDEVICE_OBJECT f8af1c78
Major!PDEVICE_OBJECT
0x81fbbf18
+0x000 Type : 0n3
+0x002 Size : 0xb8
+0x004 ReferenceCount : 0n0
+0x008 DriverObject : 0x81fa6da0 _DRIVER_OBJECT
+0x00c NextDevice : (null)
+0x010 AttachedDevice : (null)
+0x014 CurrentIrp : (null)
+0x018 Timer : (null)
+0x01c Flags : 0xc0
+0x020 Characteristics : 0x100
+0x024 Vpb : (null)
+0x028 DeviceExtension : (null)
+0x02c DeviceType : 0x22
+0x030 StackSize : 1 ''
+0x034 Queue : <unnamed-tag>
+0x05c AlignmentRequirement : 0
+0x060 DeviceQueue : _KDEVICE_QUEUE
+0x074 Dpc : _KDPC
+0x094 ActiveThreadCount : 0
+0x098 SecurityDescriptor : 0xe1000518 Void
+0x09c DeviceLock : _KEVENT
+0x0ac SectorSize : 0
+0x0ae Spare1 : 0
+0x0b0 DeviceObjectExtension : 0x81fbbfd0 _DEVOBJ_EXTENSION
+0x0b4 Reserved : (null)
可以看到当我们调用IoCreateDevice 后 就让我们创建的设备与我们的驱动联系在一起了()
接下来就是创建符号链接 IoCreateSymbolicLink
到目前为止我们已经在内核中创建了一个设备对象 一个驱动对象
那么这些设备对象是干什么用的呢? 比如我们的应用程序想使用这个驱动我们要怎么做?
DriverObject->MajorFunction[IRP_MJ_CREATE] =
DriverObject->MajorFunction[IRP_MJ_CLOSE] = MAJOR_DispatchCreateClose;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = MAJOR_DispatchDeviceControl;
DriverObject->DriverUnload = MAJOR_DriverUnload;
上面的代码就是想操作系统申请(就是告诉OS 应用程序如何使用这些驱动)
kd> dt _DRIVER_OBJECT 0x81fa6da0
nt!_DRIVER_OBJECT
+0x000 Type : 0n4
+0x002 Size : 0n168
+0x004 DeviceObject : 0x81fbbf18 _DEVICE_OBJECT
+0x008 Flags : 2
+0x00c DriverStart : 0xf899a000 Void
+0x010 DriverSize : 0x7000
+0x014 DriverSection : 0x81fddef8 Void
+0x018 DriverExtension : 0x81fa6e48 _DRIVER_EXTENSION
+0x01c DriverName : _UNICODE_STRING "\Driver\Major.sys"
+0x024 HardwareDatabase : 0x80671ae0 _UNICODE_STRING "\REGISTRY\MACHINE\HARDWARE\DESCRIPTION\SYSTEM"
+0x028 FastIoDispatch : (null)
+0x02c DriverInit : 0xf899e03e long Major!GsDriverEntry+0
+0x030 DriverStartIo : (null)
+0x034 DriverUnload : 0xf899b110 void Major!MAJOR_DriverUnload+0
+0x038 MajorFunction : [28] 0xf899b010 long Major!MAJOR_DispatchCreateClose+0
其实就是将_DRIVER_OBJECT 这个结构体的一些成员填上我们告诉OS的值
这些处理完了 我们的驱动就常驻内存中了 除非重启动或者卸载
我们来看下卸载例程
VOID MAJOR_DriverUnload(
IN PDRIVER_OBJECT DriverObject
)
{
KdBreakPoint();
PDEVICE_OBJECT pdoNextDeviceObj = pdoGlobalDrvObj->DeviceObject;
IoDeleteSymbolicLink(&usSymlinkName);
// Delete all the device objects
while(pdoNextDeviceObj)
{
PDEVICE_OBJECT pdoThisDeviceObj = pdoNextDeviceObj;
pdoNextDeviceObj = pdoThisDeviceObj->NextDevice;
IoDeleteDevice(pdoThisDeviceObj);
}
}
pdoGlobalDrvObj 就是我们的驱动对象
kd> dt _DRIVER_OBJECT 81fa6da0
nt!_DRIVER_OBJECT
+0x000 Type : 0n4
+0x002 Size : 0n168
+0x004 DeviceObject : 0x81d0b030 _DEVICE_OBJECT
+0x008 Flags : 0x13
+0x00c DriverStart : 0xf8a0a000 Void
+0x010 DriverSize : 0x7000
+0x014 DriverSection : 0x81fa6120 Void
+0x018 DriverExtension : 0x81fa6e48 _DRIVER_EXTENSION
+0x01c DriverName : _UNICODE_STRING "\Driver\Major.sys"
+0x024 HardwareDatabase : 0x80671ae0 _UNICODE_STRING "\REGISTRY\MACHINE\HARDWARE\DESCRIPTION\SYSTEM"
+0x028 FastIoDispatch : (null)
+0x02c DriverInit : 0xf8a0e03e long Major!GsDriverEntry+0
+0x030 DriverStartIo : (null)
+0x034 DriverUnload : 0xf8a0b110 void Major!MAJOR_DriverUnload+0
+0x038 MajorFunction : [28] 0xf8a0b010 long Major!MAJOR_DispatchCreateClose+0
while(pdoNextDeviceObj)
{
PDEVICE_OBJECT pdoThisDeviceObj = pdoNextDeviceObj;
pdoNextDeviceObj = pdoThisDeviceObj->NextDevice;
IoDeleteDevice(pdoThisDeviceObj);
}
这个循环变量这个驱动对象的所有设备对象 然后删除 怎么遍历的呢
原来没个设备对象都有一个指向下一个对象的指针,也就是OS会将我们创建的设备对象做成一个链表链接起来