#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/types.h>
#include <linux/string.h>
#include <linux/usb.h>
#include <linux/smp_lock.h>
#define CLEAR_CR0 asm ("pushl %eax\n\t" \
"movl %cr0, %eax\n\t" \
"andl $0xfffeffff, %eax\n\t" \
"movl %eax, %cr0\n\t" \
"popl %eax");
#define SET_CR0 asm ("pushl %eax\n\t" \
"movl %cr0, %eax\n\t" \
"orl $0x00010000, %eax\n\t" \
"movl %eax, %cr0\n\t" \
"popl %eax");
static u_char tmp[5];
static int hook_usb_match_one_id(struct usb_interface *interface,const struct usb_device_id *id);
static void hook(void)
{
u_char *buf;
long p;
buf = (u_char *)usb_match_one_id;
p = (long)hook_usb_match_one_id - (long)usb_match_one_id - (long)5;
lock_kernel();
CLEAR_CR0
memcpy(tmp, buf, 5);
buf[0] = 0xe9;
memcpy( buf + 1, &p, 4);
SET_CR0
unlock_kernel();
}
static void unhook(void)
{
u_char *buf;
lock_kernel();
CLEAR_CR0
buf = (u_char *)usb_match_one_id;
memcpy(buf, tmp, 5);
SET_CR0
unlock_kernel();
}
static int hook_usb_match_one_id(struct usb_interface *interface,const struct usb_device_id *id)
{
unsigned char bclass;
unsigned char bsubclass;
int ret;
printk("hook_usb_match_one_id() excute\n");
bclass = interface->altsetting->desc.bInterfaceClass;
bsubclass = interface->altsetting->desc.bInterfaceSubClass;
printk("bclass = %d,bsubclass = %d\n",bclass,bsubclass);
if(bclass == 8 || bclass == 255)
{
return 0;
}
else
{
unhook();
ret = usb_match_one_id(interface,id);
hook();
}
return ret;
}
static int __init init(void)
{
printk("replace usb_match_one_id()\n");
hook();
return 0;
}
static void __exit fini(void)
{
printk("restore usb_match_one_id()\n");
unhook();
}
module_init(init);
module_exit(fini);
MODULE_LICENSE("GPL");