#include #include #include #include // for current->comm, current->pid #include // for copy_from_user, copy_to_user (如果需要访问用户空间内存) #include // 包含 USB 核心数据结构,如 struct urb MODULE_LICENSE("GPL"); MODULE_AUTHOR("Leo"); MODULE_DESCRIPTION("Hook usb_submit_urb ioctl on arm64"); // 这里的注释可能不完全准确,usb_submit_urb不是ioctl,是内核函数 static struct kprobe kp; // 针对 ARM64 (AArch64) 架构,函数参数通常在 x0, x1, x2... 寄存器中。 // pt_regs 中的 regs 数组索引通常对应这些寄存器。 // 对于 AArch64,x0 是 regs[0],x1 是 regs[1],以此类推。 // usb_submit_urb 函数原型通常是:int usb_submit_urb(struct urb *urb, gfp_t mem_flags) // 所以第一个参数 struct urb *urb 应该在 x0 寄存器中,对应 regs[0]。 static int handler_pre(struct kprobe *p, struct pt_regs *regs) { // !!! 核心修改点:在 ARM64 上,函数第一个参数通常在 x0 (regs[0]) !!! struct urb *urb_kern = (struct urb *)regs->regs[0]; // 严谨的空指针检查 if (!urb_kern) { pr_err("[usbFilter] handler_pre: urb_kern is NULL. Skipping.\n"); return 0; // KPROBE_OK, 让原始函数继续执行,避免崩溃 } // 打印进程信息、PID pr_info("[usbFilter] 进程: %s, pid: %d\n", current->comm, current->pid); // 获取并打印 URB 的详细信息 pr_info("[usbFilter] URB详情: 地址=%p, pipe=0x%08x, 状态=%d, 传输标志=0x%08x\n", urb_kern, urb_kern->pipe, urb_kern->status, urb_kern->transfer_flags); // 打印 pipe 的解析信息 pr_info("[usbFilter] Pipe解析: 设备地址=%d, 端点号=%d, 方向=%s, 类型=%s\n", usb_pipedevice(urb_kern->pipe), usb_pipeendpoint(urb_kern->pipe), usb_pipein(urb_kern->pipe) ? "IN(设备到主机)" : "OUT(主机到设备)", usb_pipetype(urb_kern->pipe) == PIPE_CONTROL ? "控制传输" : usb_pipetype(urb_kern->pipe) == PIPE_ISOCHRONOUS ? "等时传输" : usb_pipetype(urb_kern->pipe) == PIPE_BULK ? "批量传输" : usb_pipetype(urb_kern->pipe) == PIPE_INTERRUPT ? "中断传输" : "未知"); // 端点信息 if (urb_kern->ep) { pr_info("[usbFilter] 端点信息: 地址=0x%02x, 属性=0x%02x, 最大包大小=%d, 间隔=%d\n", urb_kern->ep->desc.bEndpointAddress, urb_kern->ep->desc.bmAttributes, urb_kern->ep->desc.wMaxPacketSize, urb_kern->ep->desc.bInterval); } else { pr_info("[usbFilter] 端点信息: urb_kern->ep 为 NULL\n"); } // 打印设备信息(如果可用) if (urb_kern->dev) { pr_info("[usbFilter] USB设备: VID=0x%04x, PID=0x%04x\n", urb_kern->dev->descriptor.idVendor, urb_kern->dev->descriptor.idProduct); ; } // 传输缓冲区信息 pr_info("[usbFilter] 传输缓冲区: buffer=%p, length=%d, actual_length=%d\n", urb_kern->transfer_buffer, urb_kern->transfer_buffer_length, urb_kern->actual_length); // 如果是等时传输,打印相关信息 if (usb_pipetype(urb_kern->pipe) == PIPE_ISOCHRONOUS) { pr_info("[usbFilter] 等时传输: number_of_packets=%d, start_frame=%d, error_count=%d\n", urb_kern->number_of_packets, urb_kern->start_frame, urb_kern->error_count); } // 如果是控制传输,打印setup包 if (usb_pipetype(urb_kern->pipe) == PIPE_CONTROL && urb_kern->setup_packet) { struct usb_ctrlrequest *setup = (struct usb_ctrlrequest *)urb_kern->setup_packet; pr_info("[usbFilter] 控制传输Setup包: bRequestType=0x%02x, bRequest=0x%02x, wValue=0x%04x, wIndex=0x%04x, wLength=%u\n", setup->bRequestType, setup->bRequest, le16_to_cpu(setup->wValue), le16_to_cpu(setup->wIndex), le16_to_cpu(setup->wLength)); } // 传输数据内容打印 if (urb_kern->transfer_buffer && urb_kern->transfer_buffer_length > 0) { unsigned char data[32] = {0}; // 增加到32字节 unsigned int to_copy = min((unsigned int)32, urb_kern->transfer_buffer_length); // 尝试从用户空间拷贝 if (copy_from_user(data, urb_kern->transfer_buffer, to_copy) != 0) { // 0 表示成功 memcpy(data, urb_kern->transfer_buffer, to_copy); } char hex[3 * 32 + 1] = {0}; // 修改为适应32字节的大小 int i; for (i = 0; i < to_copy; ++i) { // 确保 snprintf 不会溢出 hex 缓冲区 snprintf(hex + i * 3, sizeof(hex) - (i * 3), "%02X ", data[i]); } pr_info("[usbFilter] 数据内容(hex, %u字节): %s\n", to_copy, hex); } if(urb_kern->dev->descriptor.idVendor == 0x1a86 && urb_kern->dev->descriptor.idProduct == 0x55de) { pr_info("[usbFilter] 发现目标设备,阻断提交URB\n"); regs->regs[0] = 0; // 设置 x0 寄存器(返回值)为 0 (成功) return 1; } return 0; } static int __init usb_hook_init(void) { // usb_submit_urb 是一个导出的符号,Kprobe 可以 Hook kp.symbol_name = "usb_submit_urb"; kp.pre_handler = handler_pre; if (register_kprobe(&kp) < 0) { pr_err("[usbFilter] register_kprobe failed\n"); return -1; } pr_info("[usbFilter] kprobe registered for %s at %p\n", kp.symbol_name, kp.addr); return 0; } static void __exit usb_hook_exit(void) { unregister_kprobe(&kp); pr_info("[usbFilter] kprobe unregistered\n"); } module_init(usb_hook_init); module_exit(usb_hook_exit);