首页
社区
课程
招聘
[原创]USB重定向-对开源软件USBIPSTUB框架改造,修改为类过滤机制
发表于: 2025-9-11 13:47 4272

[原创]USB重定向-对开源软件USBIPSTUB框架改造,修改为类过滤机制

2025-9-11 13:47
4272

本文是对USBIPSTUB项目进行改造,添加了类过滤机制,提升了驱动对于USB设备的兼容性。


开源项目USB重定向地址:f28K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Y4K9i4c8Z5N6h3u0Q4x3X3g2U0L8$3#2Q4x3V1k6U0k6i4A6S2L8X3&6W2i4K6u0r3N6i4y4T1K9i4m8Q4x3X3c8%4K9h3^5`.


USBIPSTUB驱动模块分为两部分,分别是在本地设备端瘦客户端,还有远程机器端。瘦客户端驱动为STUB,远端驱动为VHCI以及子设备VHUB,虚拟出来的USB设备属于VHUB管辖。


USBIPSTUB瘦客户端驱动的逻辑:usbip.exe先主动将某个USB设备安装STUB驱动,后续usbipd.exe程序接收到USB重定向请求后,遍历系统中的STUB设备,根据id找到设备后,打开此设备通信。

usbip.exe程序主动为USB设备安装STUB驱动的过程称为bind,需要先在本机上安装USB/IP 测试证书,然后程序根据设备id修改对应的cat文件以及添加设备id到对应的inf文件,接着调用UpdateDriverForPlugAndPlayDevicesA(W)函数为该设备安装STUB驱动。在客户机器上安装测试证书可能会引发安全问题,如果不使用测试证书不希望动态生成cat文件和inf文件,那么就需要提前容纳尽可能多的设备id到inf文件,交给微软签名,生成cat文件。


由于是为特定vid(供应商id)和特定pid(产品id)安装STUB驱动,因此如果系统中存在两个同类型同厂商的usb设备,那么这两个设备都会安装STUB驱动,如果只需要重定向一个设备,那么另一个设备也会安装STUB驱动无法在本地使用了。

兼容性问题,需要在inf文件中包含尽可能多的设备id,每需要多添加一个设备id,需要修改inf文件后重新交给微软签名才能兼容信的USB设备。



将瘦客户端的USBIPSTUB驱动修改为类过滤驱动(需要提供AddDevice回调函数),当系统中存在USB设备(如USB Hub和部分USB设备)时操作系统会帮忙调用这个STUB驱动的AddDevice的回调函数。


使用instdrv工具安装STUB驱动,例如服务名称为usbip_stub

需要在框架上做出的改动如下:

在注册表HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\{36fc9e60-c465-11cf-8056-444553540000}右侧添加多字符串值类型的数据,值名称为UpperFilters,这是固定的,这个值不能修改,值Value为usbip_stub 取决于你的驱动服务名称。

可以采用重启系统的方式,或者执行一段代码对系统上的Hub设备执行软插拔操作,来触发STUB类过滤驱动中的AddDevice回调函数。

下面的这段代码来自于USBDK开源项目,调用ResetDeviceByClass传入的GUID为GUID_DEVINTERFACE_USB_HOST_CONTROLLER。

   

上面代码需要在安装时如添加注册表后 执行一次,就会调用AddDevice回调函数。还有在卸载时先删除注册表内容再执行这个代码即可触发Hub设备的Remove回调例程,此时STUB驱动可以释放资源,后续需要停止驱动卸载驱动。



接下来是Attach Hub设备,AddDevice函数的部分代码:

在AddDevice中 调用了FilterDevice函数,之后就返回了STATUS_SUCCESS

FilterDevice中流程如下:

1. 根据pdo查询一个链表,判断这个pdo是否已经被保存到了链表中,如果已经存在那么直接返回,表明已经记录下了这个设备不需要处理。

2. 根据pdo查询BusQueryDeviceID属性,如果deviceid满足如下条件之一那么就认为是hub,

 (1)开头的字符串是USB\\ROOT_HUB、USB\\ROOT_HUB20、USB\\ROOT_HUB30、NUSB3\\ROOT_HUB30、IUSB3\\ROOT_HUB30 ,那么就是一个hub设备

    (2)  开头是USB\\ 并且设备描述符的bDeviceClass字段是USB_DEVICE_CLASS_HUB,那么也是一个hub设备

3. 根据pdo查询BusQueryInstanceID属性,记录下instanceid

4. 如果deviceid开头是USB\\字符串,此时需要从另一个全局链表中判断当前的deviceid和instanceid是否保存在链表中,这个链表是需要重定向的设备链表。

5. 如果一个设备既不是hub设备(即不满足步骤2)也不是需要重定向的usb设备(即不满足步骤4),那么就认为这个设备不需要attach,不需要处理,直接返回。

接下来 创建一个设备attach到pdo设备栈上,并缓存设备描述符以及产品字符串信息(方便后续应用层程序枚举)。

然后将创建的设备信息以及pdo信息保存到全局链表中,如果是hub设备那么保存到链表即可,如果是usb设备,那么还需要获取usb设备的parent对象即usb设备是在哪个hub上,这个后续说明,将usb设备插入到全局链表时还需要对parent设备的数据结构进行调整例如对子设备数量+1,并插入到parent设备对应的child设备链表中,维护这样一个父子关系。

如果是需要重定向的usb设备,那么还需要调用USBD_CreateHandle函数获取设备的usbd句柄记录下来。


接下来是拦截Hub设备的请求,当MajorFunction为IRP_MJ_PNP,并且MinorFunction为IRP_MN_QUERY_DEVICE_RELATIONS时,如果类型如下:

BusRelations == irpstack->Parameters.QueryDeviceRelations.Type

那么先下发这个请求,等待请求完成后,如果返回成功,那么此时的irp->IoStatus.Information指向的是结构体PDEVICE_RELATIONS

typedef struct _DEVICE_RELATIONS {

    ULONG Count;

    _Field_size_(Count) PDEVICE_OBJECT Objects[1];  // variable length

} DEVICE_RELATIONS, *PDEVICE_RELATIONS;


这个结构体中保存的就是hub返回的子设备,此时需要完成如下两个步骤

(1)丢弃已经移除的usb设备,比如hub上原来插入了3个usb设备,此时只有2个,那么需要从保存的hub数据结构子设备中移除对应的pdo对象(子设备数目减1并且从子设备链表移除),以及从全局设备链表中移除这个pdo数据释放对应内存,如果是一个

(2)添加新插入的usb设备,如果这个是一个usb hub,那么先不处理,因为后续系统会调用AddDevice传入此pdo,如果这个是一个usb设备,比如hub上插入了一个新的usb设备,之前没有的usb设备(此处判断如果新插入的设备需要重定向,通过一个全局重定向的链表来判断,如果此pdo对应的deviceid和instanceid需要重定向,那么将此pdo对应的parent hub对象保存到全局链表中),如果这个usb设备不需要重定向,那么获取deviceid和instanceid后添加到全局链表中并修改parent对应的数据结构,如果需要重定向,那么手动调用此驱动的AddDevice回调函数传入此pdo(在AddDevice函数中会Attach此设备)。


完成hub上的IRP_MN_QUERY_DEVICE_RELATIONS的请求拦截后,我们现在已经Attach上了usb设备,Usb设备给上层系统传入设备id等信息,操作系统根据设备id信息为设备安装合适的驱动,如果要重定向usb设备,还需要为设备patch deviceid信息,这样系统就不会安装对应驱动,不会将这个设备识别为对应的usb设备,需要拦截usb设备的MinorFunction请求为IRP_MN_QUERY_ID,需要patch BusQueryDeviceID、BusQueryInstanceID、BusQueryHardwareIDs、BusQueryCompatibleIDs


还需要修改拦截MinorFunction为IRP_MN_QUERY_CAPABILITIES的请求


[培训]Windows内核深度攻防:从Hook技术到Rootkit实战!

最后于 2025-10-13 01:05 被0346954编辑 ,原因:
收藏
免费 9
支持
分享
最新回复 (10)
雪    币: 2790
活跃值: (5496)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
2
厉害,学习下
2025-9-12 08:43
0
雪    币: 42
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
3
可以私聊吗
2025-9-15 20:44
0
雪    币: 4739
活跃值: (6073)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
可以远程使用CAD等软件的key了吧
2025-9-16 07:00
0
雪    币: 5408
活跃值: (7221)
能力值: ( LV10,RANK:160 )
在线值:
发帖
回帖
粉丝
5
piaoyi587 可以远程使用CAD等软件的key了吧
这个可以远程使用usb设备,你说的key  是usb设备吗?
2025-9-16 11:19
0
雪    币: 4739
活跃值: (6073)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
嗯 我记得有这样的工具 (驱动)  免费的
2025-9-17 17:00
0
雪    币: 894
活跃值: (14581)
能力值: ( LV12,RANK:322 )
在线值:
发帖
回帖
粉丝
7
加油
2025-9-21 06:51
0
雪    币: 5408
活跃值: (7221)
能力值: ( LV10,RANK:160 )
在线值:
发帖
回帖
粉丝
8
一半人生 加油[em_079]
谢谢
2025-9-21 11:02
0
雪    币: 229
活跃值: (663)
能力值: ( LV10,RANK:170 )
在线值:
发帖
回帖
粉丝
9
开源usbip-win最大的问题在于客户端驱动写的有点烂,特别是wdm版本 需要大改
2025-9-28 15:10
0
雪    币: 199
活跃值: (764)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
uspip玩玩还行,商用建议重构,不然一大堆坑等你填
2025-11-25 16:42
0
雪    币: 5408
活跃值: (7221)
能力值: ( LV10,RANK:160 )
在线值:
发帖
回帖
粉丝
11
看来还有很多地方要提高啊。
2025-12-6 00:18
0
游客
登录 | 注册 方可回帖
返回