关于设备绑定的那些事

据msdn上说绑定设备最开始是用的是IoAttachDeviceByPointer,其原型为

 

 

NTSTATUS IoAttachDeviceByPointer(

IN PDEVICE_OBJECT SourceDevice,

IN PDEVICE_OBJECT TargetDevice

);

 

第一个参数为待绑定的设备,第二个参数为绑定的目标设备,返回值确定是否成功


而取代IoAttachDeviceByPointer的则是IoAttachDeviceToDeviceStack与IoAttachDeviceToDeviceStackSafe

 

IoAttachDeviceToDeviceStack的原型为
PDEVICE_OBJECT IoAttachDeviceToDeviceStack(
__in  PDEVICE_OBJECT SourceDevice,
__in  PDEVICE_OBJECT TargetDevice
);


IoAttachDeviceToDeviceStack函数参数和IoAttachDeviceByPointer一样,

 

但是返回值由NTSTATUS改为了PDEVICE_OBJECT,


返回成功挂载后的下一层设备,这个和第二个参数有区别...假如a--b--c--d--e依次为设备栈的底到顶,若将f挂载到a上面的

 

话,调用IoAttachDeviceToDeviceStack(f,a),挂载之后返回的指针指向e,与第二个参数不同,此时的设备栈为a--b--c--d--e--f,


f被挂载在设备栈的顶层.

 

逆向xp sp3下的IoAttachDeviceToDeviceStack后发现,它本质上还是调用了IoAttachDeviceToDeviceStackSafe

 

 

8050cb42 8bff            mov     edi,edi

8050cb44 55              push    ebp

8050cb45 8bec            mov     ebp,esp

8050cb47 6a00            push    0 ;第三个参数为0

8050cb49 ff750c          push    dword ptr [ebp+0Ch]  ;压入第二个参数

8050cb4c ff7508          push    dword ptr [ebp+8] ;压入第一个参数

8050cb4f e8caf2ffff      call    nt!IopAttachDeviceToDeviceStackSafe (8050be1e) ;调用

8050cb54 5d              pop     ebp

8050cb55 c20800          ret     8

 


IoAttachDeviceToDeviceStack函数参数和IoAttachDeviceByPointer一样,

 

但是返回值由NTSTATUS改为了PDEVICE_OBJECT,


返回成功挂载后的下一层设备,这个和第二个参数有区别...

 

 

NTSTATUS IoAttachDeviceToDeviceStackSafe(
__in PDEVICE_OBJECT SourceDevice,
__in PDEVICE_OBJECT TargetDevice,
__out PDEVICE_OBJECT *AttachedToDeviceObject
);

而IoAttachDeviceToDeviceStackSafe的返回值为NTSTATUS,并且第三个参数返回挂载成功后的下一层设备.

NTSTATUSNTAPI

IoAttachDeviceToDeviceStackSafe(IN PDEVICE_OBJECT SourceDevice,

                              IN PDEVICE_OBJECT TargetDevice,

                              IN OUT PDEVICE_OBJECT *AttachedToDeviceObject)

{

    /* Call the internal function */

    if (!IopAttachDeviceToDeviceStackSafe(SourceDevice, TargetDevice,

                                          AttachedToDeviceObject))

    {

        /* Nothing found */

        return STATUS_NO_SUCH_DEVICE;

    }

    return STATUS_SUCCESS;

}

PDEVICE_OBJECT NTAPI

IopAttachDeviceToDeviceStackSafe(IN PDEVICE_OBJECT SourceDevice,

                      IN PDEVICE_OBJECT TargetDevice,

                      OUT PDEVICE_OBJECT *AttachedToDeviceObject OPTIONAL)

{

    PDEVICE_OBJECT AttachedDevice;

    PEXTENDED_DEVOBJ_EXTENSION SourceDeviceExtension;

    /* Get the Attached Device and source extension */

    AttachedDevice = IoGetAttachedDevice(TargetDevice);

    SourceDeviceExtension = IoGetDevObjExtension(SourceDevice);

    ASSERT(SourceDeviceExtension->AttachedTo == NULL);

    /* Make sure that it's in a correct state */

    if ((AttachedDevice->Flags & DO_DEVICE_INITIALIZING) ||

        (IoGetDevObjExtension(AttachedDevice)->ExtensionFlags &

         (DOE_UNLOAD_PENDING | DOE_DELETE_PENDING |

          DOE_REMOVE_PENDING | DOE_REMOVE_PROCESSED)))

    {   //尚在初始化的过程中,或者已在卸载的过程中,不再堆叠

        /* Device was unloading or being removed */

        AttachedDevice = NULL;

    }

    else

    {   //堆叠,这里的AttachedDevice是粘贴的目标,SourceDevice是被粘贴对象

        /* Update atached device fields */

        AttachedDevice->AttachedDevice = SourceDevice;  //向上指向被粘贴对象

        AttachedDevice->Spare1++;

        /* Update the source with the attached data */

        SourceDevice->StackSize = AttachedDevice->StackSize + 1;  //堆叠的深度增加了

        SourceDevice->AlignmentRequirement = AttachedDevice->AlignmentRequirement;

        SourceDevice->SectorSize = AttachedDevice->SectorSize;

        /* Check for pending start flag */

        if (IoGetDevObjExtension(AttachedDevice)->ExtensionFlags &

                                                     DOE_START_PENDING)

        {

            /* Propagate */

            IoGetDevObjExtension(SourceDevice)->ExtensionFlags |=

                                                     DOE_START_PENDING;

        }

        /* Set the attachment in the device extension */

        SourceDeviceExtension->AttachedTo = AttachedDevice;  //向下指向粘贴目标

    }

    /* Return the attached device */  //使自定义的向下指针也指向粘贴目标

    if (AttachedToDeviceObject) *AttachedToDeviceObject = AttachedDevice;

    return AttachedDevice;

}

两个函数运行的IRQL<=DISPATCH_LEVEL.
IoDetachDevice,取消挂载的设备,原型为
VOID IoDetachDevice(
__inout  PDEVICE_OBJECT TargetDevice
);
其取消TargetDevice的引用计数,当引用计数为0后就卸载

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值