#if 0 # /bin/sh << EOS MODNAME=\`basename "$0" .c\` set -x gcc -O -fbuiltin -fomit-frame-pointer -fPIC -shared -o \$MODNAME.so "$0" -ldl EOS exit # #endif #ifndef __linux # error "Linux only" #endif #define _LIBC #define _LIBC_REENTRANT #include #include #include #include #include #include #include #include #include #include #include #include #ifdef __GNU_LIBRARY__ # if __GNU_LIBRARY__==6 # define LIBC_SO "libc.so.6" # else # define LIBC_SO "libc.so.5" # endif #else # error "what's your libc?" #endif static int (*__libc_ioctl)(int f, int request, ...); asm (" .section \".init\" call _dev_cdrom_init "); static _dev_cdrom_init() { char *env; uid_t uid; void *libh; if (!(libh = dlopen (LIBC_SO,RTLD_LAZY))) { fprintf (stderr,"can't dlopen(\"%s\").",LIBC_SO); exit (1); } if (!(__libc_ioctl = (int (*)(int,int,...))dlsym (libh,"ioctl"))) { fprintf (stderr,"can't link to \"ioctl\" from %s",LIBC_SO); exit (1); } } static int _lntox(unsigned char *p,int n,char *s) { static char conv[]="0123456789ABCDEF"; int i; for (i=0;i>4)&0xF], s[1]=conv[p[0]&0xF], s[2]=' '; return n*3; } static int my_ioctl (const void *ra,int fd,int request,void *p) { int ret,len; unsigned char c; static char out[128]; #if 1 if (request == SG_IO) { struct sg_io_hdr *arg=(struct sg_io_hdr *)p; ret=(*__libc_ioctl)(fd,request,arg); c=arg->cmdp[0]; if (c!=0x28 /* READ(10) */ && c!=0x2A /* WRITE(10) */ && c!=0x00 /* TEST UNIT READY */ && c!=0x4A /* GET NOTIFICATION */ && c!=0x1E /* PREVENT REMOVAL */ && c!=0x5C /* READ BUFFER CAPACITY */ ) { len=_lntox(arg->cmdp,10,out); if (arg->dxfer_direction != SG_DXFER_NONE) { out[len-1]=arg->dxfer_direction&1?'<':'>'; len+=_lntox(arg->dxferp,arg->dxfer_len>16?16:arg->dxfer_len,out+len); out[len++]='\n'; out[len]='\0'; } else { out[len++]='\n';out[len]='\0'; } write(2,out,len); } return ret; } else if (request == CDROM_SEND_PACKET) { struct cdrom_generic_command *arg=(struct cdrom_generic_command *)p; ret=(*__libc_ioctl)(fd,request,arg); c=arg->cmd[0]; if (c!=0x28 /* READ(10) */ && c!=0x2A /* WRITE(10) */ && c!=0x00 /* TEST UNIT READY */ && c!=0x4A /* GET NOTIFICATION */ && c!=0x1E /* PREVENT REMOVAL */ && c!=0x5C /* READ BUFFER CAPACITY */ ) { len=_lntox(arg->cmd,10,out); if (arg->data_direction != CGC_DATA_NONE) { out[len-1]=arg->data_direction&1?'>':'<'; len+=_lntox(arg->buffer,arg->buflen>16?16:arg->buflen,out+len); out[len++]='\n'; out[len]='\0'; } else { out[len++]='\n';out[len]='\0'; } write(2,out,len); } return ret; } #endif return -38; } asm (" .text .type ioctl,@function .global ioctl .align 4 ioctl: call my_ioctl cmpl $-38,%eax jne 1f jmp *__libc_ioctl 1: ret .size ioctl,.-ioctl ");