//------------------------------------------------------------------- // newcall.c // // This module dynamically installs a new system-call, without // the need to modify and recompile the kernel's source files. // It is based on 'patching' an obsolete entry in the kernel's // 'sys_call_table[]' array. The address of that array can be // discovered, either in the 'System.map' file for the current // kernel (normally located in the '/boot' directory), or else // in the uncompressed kernel binary ELF file ('vmlinux') left // behind in the '/usr/src/linux' directory after compilation. // // NOTE: Written and tested using Linux kernel version 2.4.17. // // written on: 22 JUN 2004 // revised on: 09 MAY 2005 -- for Linux kernel version 2.6.10 //------------------------------------------------------------------- #include // for init_module() #include // for copy_to/from_user() #include // for __NR_break char modname[] = "newcall"; extern unsigned long *sys_call_table; unsigned long save_old_syscall; asmlinkage long my_syscall( int __user * num ) { int val; if ( copy_from_user( &val, num, sizeof( int ) ) ) return -EFAULT; ++val; if ( copy_to_user( num, &val, sizeof( int ) ) ) return -EFAULT; return 0; // SUCCESS } int init_module( void ) { printk( "<1>\nInstalling \'%s\' module ", modname ); printk( "(sys_call_table[] at %08X) \n", (int)sys_call_table ); printk( "\nInstalling new function for system-call %d\n", __NR_break ); save_old_syscall = sys_call_table[ __NR_break ]; sys_call_table[ __NR_break ] = (unsigned long)my_syscall; return 0; // SUCCESS } void cleanup_module( void ) { printk( "<1>Removing \'%s\' module\n", modname ); sys_call_table[ __NR_break ] = save_old_syscall; } MODULE_LICENSE("GPL");