diff --git a/Makefile b/Makefile index 1d91fde..81cc87f 100644 --- a/Makefile +++ b/Makefile @@ -3,8 +3,30 @@ obj-m += libusbMod.o KDIR := /lib/modules/$(shell uname -r)/build PWD := $(shell pwd) -all: +CC := gcc +CFLAGS := -Wall -O2 +LIBS := -lusb-1.0 + +# 默认目标:同时编译内核模块和用户程序 +all: libusbMod.ko main + +# 编译内核模块 +libusbMod.ko: make -C $(KDIR) M=$(PWD) modules +# 编译用户态程序 main +main: main.c + $(CC) $(CFLAGS) -o $@ $< $(LIBS) + +# 清理所有生成文件 clean: - make -C $(KDIR) M=$(PWD) clean \ No newline at end of file + make -C $(KDIR) M=$(PWD) clean + $(RM) main + +# 加载模块 +load: + sudo insmod libusbMod.ko + +# 卸载模块 +unload: + sudo rmmod libusbMod diff --git a/libusbMod.c b/libusbMod.c index 22eb6ad..93794dd 100644 --- a/libusbMod.c +++ b/libusbMod.c @@ -3,6 +3,7 @@ #include #include #include +#include // for copy_from_user MODULE_LICENSE("GPL"); MODULE_AUTHOR("Leo"); @@ -13,11 +14,36 @@ static struct kprobe kp; static int handler_pre(struct kprobe *p, struct pt_regs *regs) { unsigned int cmd = 0; + struct usbdevfs_urb urb_kern; + struct usbdevfs_urb __user *urb_user; cmd = (unsigned int)regs->regs[1]; // ioctl 的第二个参数 if (cmd == USBDEVFS_SUBMITURB) { - pr_info("[usbFilter] process: %s, pid: %d, called USBDEVFS_SUBMITURB ioctl\n", current->comm, current->pid); + urb_user = (struct usbdevfs_urb __user *)regs->regs[2]; // 第三个参数 + if (urb_user) { + if (copy_from_user(&urb_kern, urb_user, sizeof(struct usbdevfs_urb)) == 0) { + pr_info("[usbFilter] process: %s, pid: %d, ep: 0x%x, len: %d\n", + current->comm, current->pid, + urb_kern.endpoint, urb_kern.buffer_length); + + if (urb_kern.buffer && urb_kern.buffer_length > 0) { + unsigned char data[16] = {0}; + unsigned int to_copy = urb_kern.buffer_length > 16 ? 16 : urb_kern.buffer_length; + if (copy_from_user(data, urb_kern.buffer, to_copy) == 0) { + char hex[3 * 16 + 1] = {0}; + int i; + for (i = 0; i < to_copy; ++i) + snprintf(hex + i * 3, 4, "%02X ", data[i]); + pr_info("[usbFilter] first %u bytes (hex): %s\n", to_copy, hex); + } else { + pr_warn("[usbFilter] copy_from_user buffer failed\n"); + } + } + } else { + pr_warn("[usbFilter] copy_from_user failed\n"); + } + } } return 0; } diff --git a/main.c b/main.c new file mode 100644 index 0000000..d198ba9 --- /dev/null +++ b/main.c @@ -0,0 +1,61 @@ +#include +#include +#include + +#define VENDOR_ID 0x1a86 // 替换为你的设备 VID +#define PRODUCT_ID 0x55de // 替换为你的设备 PID +#define BULK_EP_OUT 0x06 // OUT端点地址(低位为0表示OUT) +#define INTERFACE_NUMBER 4 // USB接口编号 + +int main(void) { + libusb_device_handle *handle = NULL; + int r; + int transferred; + unsigned char send_data[] = {0x01, 0x02, 0x03, 0x04, 0x05}; // 要发送的数据 + + // 初始化libusb + r = libusb_init(NULL); + if (r < 0) { + fprintf(stderr, "Failed to init libusb: %s\n", libusb_error_name(r)); + return EXIT_FAILURE; + } + + // 打开设备 + handle = libusb_open_device_with_vid_pid(NULL, VENDOR_ID, PRODUCT_ID); + if (!handle) { + fprintf(stderr, "Failed to open device\n"); + libusb_exit(NULL); + return EXIT_FAILURE; + } + + // 获取接口权限(可选,部分系统如Linux必须) + if (libusb_kernel_driver_active(handle, INTERFACE_NUMBER)) { + libusb_detach_kernel_driver(handle, INTERFACE_NUMBER); + } + + r = libusb_claim_interface(handle, INTERFACE_NUMBER); + if (r < 0) { + fprintf(stderr, "Failed to claim interface: %s\n", libusb_error_name(r)); + libusb_close(handle); + libusb_exit(NULL); + return EXIT_FAILURE; + } + + // 发送数据(Bulk OUT) + r = libusb_bulk_transfer(handle, BULK_EP_OUT, send_data, sizeof(send_data), &transferred, 1000); + if (r == 0) { + printf("Sent %d\n", transferred); + if (transferred != sizeof(send_data)) { + fprintf(stderr, "Warning: Only %d of %zu bytes sent\n", transferred, sizeof(send_data)); + } + } else { + fprintf(stderr, "Failed to send data: %s\n", libusb_error_name(r)); + } + + // 释放接口 & 关闭 + libusb_release_interface(handle, INTERFACE_NUMBER); + libusb_close(handle); + libusb_exit(NULL); + + return EXIT_SUCCESS; +}