MSO-Hansi-font-family: calibri "> Method 1: modify the system call table (applicable to linux-2.4Calibri; MSO-Hansi-font-family: calibri"> kernel)
The kernel uses sys_call_tablecalibri; MSO-Hansi-font-family: calibri "> array to store the system call table. The system call number corresponds to the system call processing function by modifying sys_call_tablecalibri; MSO-Hansi-font-family: calibri "> an element of the array can intercept system calls. In the 2.4mso-Hansi-font-family: calibri"> kernel, the sys_call_table symbol is exported and can be used by external modules. Therefore, it can be used to easily intercept system calls. When loading a module, modify sys_call_tablecalibri; MSO-Hansi-font-family: calibri ">, save its original value, and restore its processing function when uninstalling the module.
In the 2.6mso-Hansi-font-family: calibri "> kernel, because the sys_call_table symbol is invisible, you can find sys_call_tablecalibri; MSO-Hansi-font-family in the memory on the Internet: calibri "> the address method is complex and has not been clarified yet.
MSO-Hansi-font-family: calibri "> Method 2: Modify the vfsmso-Hansi-font-family: calibri"> operation table
MSO-ascii-font-family: calibri; MSO-Hansi-font-family: calibri "> This method can only intercept vfsmso-Hansi-font-family: calibri "> related system calls are implemented by modifying the file_operations, inode_operationscalibri; MSO-Hansi-font-family: calibri"> member operation functions. The Code is as follows:
#include <linux/sched.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> #include <linux/fs.h> #include <linux/file.h>
MODULE_LICENSE("GPL");
char *root_fs="/";
typedef int (*readdir_t)(struct file *,void *,filldir_t); readdir_t orig_root_readdir=NULL;
int myreaddir(struct file *fp,void *buf,filldir_t filldir) { int r; printk("<1>You got me partner!\n"); r=orig_root_readdir(fp,buf,filldir); return r; }
int patch_vfs(const char *p,readdir_t *orig_readdir,readdir_t new_readdir) { struct file *filep; filep=filp_open(p,O_RDONLY,0); if(IS_ERR(filep)) return -1; if(orig_readdir) *orig_readdir=filep->f_op->readdir;
filep->f_op->readdir=new_readdir; struct file_operations *fop = filep->f_op; fop->readdir = new_readdir; filep->f_op = fop; filp_close(filep,0); return 0; }
int unpatch_vfs(const char *p,readdir_t orig_readdir) { struct file *filep; filep=filp_open(p,O_RDONLY,0); if(IS_ERR(filep)) return -1; filep->f_op->readdir=orig_readdir; struct file_operations *fop = filep->f_op; fop->readdir = orig_readdir; filep->f_op = fop; filp_close(filep,0); return 0; }
static int patch_init(void) { patch_vfs(root_fs,&orig_root_readdir,myreaddir); printk("<1>VFS is patched!\n"); return 0; } static void patch_cleanup(void) { unpatch_vfs(root_fs,orig_root_readdir); printk("<1>VFS is unpatched!\n"); } module_init(patch_init); module_exit(patch_cleanup);
|
MSO-Hansi-font-family: calibri "> the above modules cannot be compiled on the linux-2.6.19 kernel, and the error message is: readdircalibri; MSO-Hansi-font-family: calibri "> A member is read-only and cannot be assigned a value (in red ). So I introduced an intermediate variable to modify the operation table (change the red part to the blue part ).
Reference: http://hi.baidu.com/linzhangkun/blog/item/34fe208f268d37f3503d920d.html