Compare commits

...

7 Commits

Author SHA1 Message Date
lumos
bec6c9f739 兼容了x86架构和arm64架构,去掉了阻断和修改的逻辑,后续放在用户开间用frida做,这个只做为调试查看用; 2025-06-22 12:45:13 +08:00
kylin_bg
906540dba9 加入了将控制传输数据清0的测试,目前已经注释 2025-06-07 17:42:56 +08:00
kylin_bg
3e4d3d9640 增加了回调处理,如果放行控制传输数据,可以查看到返回的数据 2025-06-07 17:00:07 +08:00
kylin_bg
7ce2f1d575 加入更多打印信息,加入设备控制 2025-06-07 16:12:09 +08:00
kylin_bg
4f2d1c0830 默认不阻断状态 2025-06-07 15:04:52 +08:00
kylin_bg
6c40865f39 Refactor kprobe handler for usb_submit_urb to improve data copying and logging on ARM64;
目前可以阻断,但是会返回用户空间错误码,并且只在libusb模式下测试过了,键盘设备会卡建
2025-06-07 12:59:17 +08:00
kylin_bg
4bba36cdb9 1. main函数测试libusb传输功能;
2. liusbmod目前可以打印抓取到传输的数据是什么;打印只能打印16个字节
2025-06-02 23:00:30 +08:00
2 changed files with 88 additions and 14 deletions

View File

@ -3,8 +3,21 @@ obj-m += libusbMod.o
KDIR := /lib/modules/$(shell uname -r)/build KDIR := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd) PWD := $(shell pwd)
all: # 默认目标:只编译内核模块
all: libusbMod.ko
# 编译内核模块
libusbMod.ko:
make -C $(KDIR) M=$(PWD) modules make -C $(KDIR) M=$(PWD) modules
# 清理所有生成文件
clean: clean:
make -C $(KDIR) M=$(PWD) clean make -C $(KDIR) M=$(PWD) clean
# 加载模块
load:
sudo insmod libusbMod.ko
# 卸载模块
unload:
sudo rmmod libusbMod

View File

@ -1,44 +1,105 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/usbdevice_fs.h>
#include <linux/kprobes.h> #include <linux/kprobes.h>
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/uaccess.h>
#include <linux/usb.h>
#include <linux/slab.h>
#include <linux/version.h>
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_AUTHOR("Leo"); MODULE_AUTHOR("Leo");
MODULE_DESCRIPTION("Hook USBDEVFS_SUBMITURB ioctl on arm64"); MODULE_DESCRIPTION("Monitor usb_submit_urb() data submission only");
static struct kprobe kp; static struct kprobe kp;
// 兼容 x86_64 和 arm64 获取第一个参数
static struct urb *get_urb_from_regs(struct pt_regs *regs)
{
#if defined(CONFIG_ARM64)
return (struct urb *)regs->regs[0];
#elif defined(CONFIG_X86_64)
return (struct urb *)regs->di;
#else
#error "Unsupported architecture"
#endif
}
static int handler_pre(struct kprobe *p, struct pt_regs *regs) static int handler_pre(struct kprobe *p, struct pt_regs *regs)
{ {
unsigned int cmd = 0; struct urb *urb_kern = get_urb_from_regs(regs);
cmd = (unsigned int)regs->regs[1]; // ioctl 的第二个参数 if (!urb_kern)
return 0;
if (cmd == USBDEVFS_SUBMITURB) { pr_info("[usbFilter] 提交URB进程: %s (pid: %d)\n", current->comm, current->pid);
pr_info("[usbFilter] process: %s, pid: %d, called USBDEVFS_SUBMITURB ioctl\n", current->comm, current->pid);
if (urb_kern->dev) {
pr_info("[usbFilter] USB设备: busnum=%d, devnum=%d, VID=0x%04x, PID=0x%04x\n",
urb_kern->dev->bus->busnum,
urb_kern->dev->devnum,
urb_kern->dev->descriptor.idVendor,
urb_kern->dev->descriptor.idProduct);
} }
pr_info("[usbFilter] URB: %p, pipe=0x%x, flags=0x%x\n",
urb_kern, urb_kern->pipe, urb_kern->transfer_flags);
pr_info("[usbFilter] pipe: 端点=%d, 方向=%s, 类型=%s\n",
usb_pipeendpoint(urb_kern->pipe),
usb_pipein(urb_kern->pipe) ? "IN" : "OUT",
usb_pipetype(urb_kern->pipe) == PIPE_CONTROL ? "CONTROL" :
usb_pipetype(urb_kern->pipe) == PIPE_ISOCHRONOUS ? "ISO" :
usb_pipetype(urb_kern->pipe) == PIPE_BULK ? "BULK" :
usb_pipetype(urb_kern->pipe) == PIPE_INTERRUPT ? "INTERRUPT" : "UNKNOWN");
// 打印控制传输的setup包内容
if (usb_pipetype(urb_kern->pipe) == PIPE_CONTROL && urb_kern->setup_packet) {
char setup_hex[3 * 8 + 1] = {0};
int i;
unsigned char *setup = (unsigned char *)urb_kern->setup_packet;
for (i = 0; i < 8; ++i) {
snprintf(setup_hex + i * 3, sizeof(setup_hex) - i * 3, "%02X ", setup[i]);
}
pr_info("[usbFilter] 控制传输setup包(8字节hex): %s\n", setup_hex);
}
// 打印控制传输的数据内容
if (urb_kern->transfer_buffer && urb_kern->transfer_buffer_length > 0) {
unsigned int to_copy = min(32U, (unsigned int)urb_kern->transfer_buffer_length);
unsigned char data[32] = {0};
memcpy(data, urb_kern->transfer_buffer, to_copy);
char hex[3 * 32 + 1] = {0};
int i;
for (i = 0; i < to_copy; ++i) {
snprintf(hex + i * 3, sizeof(hex) - i * 3, "%02X ", data[i]);
}
pr_info("[usbFilter] 提交数据(前32字节hex): %s\n", hex);
}
return 0; return 0;
} }
static int __init usb_hook_init(void) static int __init usb_hook_init(void)
{ {
kp.symbol_name = "usbdev_do_ioctl"; kp.symbol_name = "usb_submit_urb";
kp.pre_handler = handler_pre; kp.pre_handler = handler_pre;
if (register_kprobe(&kp) < 0) { if (register_kprobe(&kp) < 0)
pr_err("[usbFilter] register_kprobe failed\n"); {
pr_err("[usbFilter] 无法注册 kprobe\n");
return -1; return -1;
} }
pr_info("[usbFilter] kprobe registered for %s\n", kp.symbol_name);
pr_info("[usbFilter] 成功 hook usb_submit_urb()\n");
return 0; return 0;
} }
static void __exit usb_hook_exit(void) static void __exit usb_hook_exit(void)
{ {
unregister_kprobe(&kp); unregister_kprobe(&kp);
pr_info("[usbFilter] kprobe unregistered\n"); pr_info("[usbFilter] 已卸载 usb_submit_urb hook\n");
} }
module_init(usb_hook_init); module_init(usb_hook_init);