热度 1
IDE硬盘的序列号只需要调用一个ioctl就可以,google一下就出来了。但是我发现很多人说SCSI硬盘没有序列号,那么在我机器上scsiinfo -a /dev/sda打印出来的是什么。。。。?
Vendor: ATA
Product: HTS541080G9SA00
Revision level: MB4I
Serial Number ' MPBDPAXNHPUY1M'
于是apt-get source scsitools, 分析一下scsiinfo的源码就知道如何获取SCSI硬盘的序列号了,用了SG_IO这个ioctl, 参数是一个sg_io_hdr_t 结构体。想要修改它只需要欺骗应用程序就行了,写一个module,截获这个ioctl并将自己想要的值返回给应用程序。不过2.6内核sys_call_table好像不导出了,那么在/boot/System.map-`uname -r`这个文件中查找sys_call_table的入口地址直接写到程序里,代码如下,把SCSI硬盘序列号改成全A:
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <scsi/scsi.h>
#include <scsi/sg.h>
void **sys_call_table;
#define __NR_ioctl 54
typedef struct{
int a[2];
}id;
asmlinkage long (*old_ioctl)(unsigned int fd, unsigned int cmd, unsigned long arg);
asmlinkage long new_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
{
if(cmd == SG_IO) {
int i;
sg_io_hdr_t sgh = *(sg_io_hdr_t *)arg;
unsigned char *cmdp = sgh.cmdp;
unsigned char *buffer = sgh.dxferp;
if(cmdp[0]==0x12 && cmdp[2]==0x80) {
int ret = (*old_ioctl)(fd, cmd, arg);
int leng = buffer[3];
for(i = 0; i < leng; i++)
buffer[4 + i] = 'A';
buffer[4 + i] = '\0';
} else
return (*old_ioctl)(fd, cmd, arg);
return 0;
} else
return (*old_ioctl)(fd, cmd, arg);
}
int syscall_init(void)
{
printk("syscall_init!\n");
sys_call_table=(void *)0xc02824c0;
old_ioctl=sys_call_table[__NR_ioctl];
sys_call_table[__NR_ioctl]=&new_ioctl;
return 0;
}
void syscall_exit(void)
{
sys_call_table[__NR_ioctl]=old_ioctl;
printk("syscall_exit!\n");
}
module_init(syscall_init);
module_exit(syscall_exit);
MODULE_LICENSE("GPL");
insmod这个模块后再scsiinfo -a /dev/sda看看?
Vendor: ATA
Product: HTS541080G9SA00
Revision level: MB4I
Serial Number 'AAAAAAAAAAAAAAAAA'
OK,可以用。
|Archiver|手机版|小黑屋|软路由 ( 渝ICP备15001194号-1|渝公网安备 50011602500124号 )
GMT+8, 2024-6-3 08:03 , Processed in 0.048615 second(s), 5 queries , Gzip On, Redis On.
Powered by Discuz! X3.5 Licensed
© 2001-2023 Discuz! Team.