第一个驱动 入口 卸载分析

我们知道每个驱动程序都有一个入口点

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会将我们创建的设备对象做成一个链表链接起来




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值