//------------------------------------------------------------------- // myexport.c // // This module creates a pseudo-file (named '/proc/myexport') // which allows other modules to be dynamically linked to the // kernel's 'sys_call_table[]' data-structure, simulating the // effect of having recompiled the kernel with this symbol as // an 'exported' (i.e., publicly visible) object. The actual // address at which that array resides within the kernel will // depend upon specific configuration options in effect while // the kernel was being compiled, but can be determined by an // inspection of the (uncompressed) kernel binary ('vmlinux') // or from its associated 'System.map' file; in any case, the // address must be supplied by the user as a module-parameter // at the time this module is being installed, for example: // // root# /sbin/insmod myexport.o svctable=C032F974 // // For convenience, we recommend that a shell-script be used // so as to automate these address-lookup and module-install // steps (and avoid hazards caused by parameter mis-typing). // // Warning: This technique is definitely a kernel 'hack' and // justified only for strictly limited educational purposes! // // NOTE: Written and tested with Linux kernel version 2.4.26. // // programmer: ALLAN CRUSE // written on: 28 SEP 2004 //------------------------------------------------------------------- #include // for init_module(), printk() #include // for create_proc_info_entry() #define PROC_DIR NULL // use the default directory #define FILE_MODE 0 // use the default file mode static char modname[] = "myexport"; // name for the file unsigned long *sys_call_table; // exported variable char *svctable = ""; // parameter pointer MODULE_PARM( svctable, "s" ); // setup by 'insmod' static int my_get_info( char *system_buffer, char **my_buffer, off_t file_position, int system_buffer_length ) { int len = 0; len += sprintf( system_buffer+len, "sys_call_table[]=" ); len += sprintf( system_buffer+len, "%08X \n", sys_call_table ); return len; } int init_module( void ) { unsigned long myval; printk( "<1>\nInstalling \'%s\' module ", modname ); printk( "with svctable=%s \n", svctable ); // converts the character-string argument to binary myval = simple_strtoul( svctable, NULL, 16 ); // assigns the resulting value to a public variable sys_call_table = (unsigned long *)myval; // a 'sanity check' (in case parameter was omitted) if ( sys_call_table == NULL ) return -EINVAL; create_proc_info_entry( modname, 0, NULL, my_get_info ); return 0; //SUCCESS } void cleanup_module( void ) { remove_proc_entry( modname, NULL ); printk( "<1>Removing \'%s\' module\n", modname ); } MODULE_LICENSE("GPL");