LibUSB简介
libusb 是一个用户态库,它通过 usbfs(又名 usbdevfs)与内核中的 USB 栈交互,主要依赖 ioctl 机制来实现控制、批量、同步等传输。libusb 最终是通过系统调用 ioctl 与内核中的 /dev/bus/usb 设备节点进行通信其中:
1 |
|
这个调用是 libusb 进行异步传输时最常用的操作,而同步传输(如 libusb_bulk_transfer, libusb_control_transfer 等)也是通过同步的 SUBMITURB + REAPURB 来完成的。
libusb的调用链层:
1 |
|
Hook函数架构
usbdev_do_ioctl(), 它的路径在drivers/usb/core/devio.c,功能是处理来自用户态的ioctl调用,是所有 USB 传输的总入口。如果想知道上位机通过 libusb 或 usbfs 向外设发送的具体数据内容(例如 control、bulk、interrupt 传输的数据),你需要在 usbdev_do_ioctl 中拦截下特定的 IOCTL 命令,如:
USBDEVFS_CONTROL(控制传输)USBDEVFS_BULK(批量传输)USBDEVFS_SUBMITURB(异步传输,核心数据封装在 URB 中)
可以通过hook 判断 cmd 类型,并从用户态通过 arg 拷贝出传输数据,架构如下:
1 |
|
Tips: 关于同步传输和异步传输的说明
| 类型 | 描述 | 使用的 IOCTL 命令 | 底层数据结构 | 调用后行为 |
|---|---|---|---|---|
| 同步传输(阻塞) | 用户态程序调用 libusb_bulk_transfer()、libusb_control_transfer() 这类接口时,会阻塞等待传输完成,直到内核返回结果。 |
USBDEVFS_BULK, USBDEVFS_CONTROL, USBDEVFS_INTERRUPT |
usbdevfs_bulktransfer, usbdevfs_ctrltransfer 等 |
调用时阻塞直到完成 |
| 异步传输(非阻塞) | 用户态程序使用 libusb_submit_transfer() 提交一个异步任务(URB),不会等待传输完成,而是由内核在完成后发出通知(通过回调或 poll)。 |
USBDEVFS_SUBMITURB, USBDEVFS_DISCARDURB |
usbdevfs_urb |
立即返回,不阻塞,内核异步完成后再通知 |