Linux Process Invisibility

Hello again, we have given a project in System Programming course. It was expected you to alter the kernel code for process invisibility, when you ps, process can not be seen in the output, if process invisibility flag is “1”.

The project was modifying the linux kernel for process invisibility, writing a system call for setting the invisibility flag and writing a user-space program.

Project was developed at Xubuntu 9.10 guest on Windows 7 host. Eclipse (with CDT and Remote System Explorer plugins) was the development IDE. Putty SSH client was also used for executing commands and “command copy/paste” availability. VirtualBox was the virtual machine supervisor.

ATTENTION: This code is experimental. If you try, it will be your own responsibility.

Preliminaries

First you must install linux-source and kernel-package packages. And then extract the package. You can install fakeroot package for compiling the kernel without becoming root.

apt-get install linux-source kernel-package
tar xjvf usr/src/linux-source*


Modifications on Kernel

.(dot, the current directory) is /usr/src/linux or /usr/src/linux-KERNEL_VERSION.

  1. . In ./include/linux/sched.h, task_struct structure (the process descriptor), we add an invisible flag to describe process’ invisibility:
    struct task_struct {
    	...
          ...
    	int invisible;
    };
    
  2. In ./kernel/sched.c, we altered task_rq_lock, task_rq_unlock and find_process_by_pid function to non-static because of the fact that they were called in another object file.
    < static struct rq *task_rq_lock(struct task_struct *p, unsigned long *flags) 
    > struct rq *task_rq_lock(struct task_struct *p, unsigned long *flags)
    < static inline void task_rq_unlock(struct rq *rq, unsigned long *flags) 
    > inline void task_rq_unlock(struct rq *rq, unsigned long *flags)
    < static struct task_struct *find_process_by_pid(pid_t pid) 
    > struct task_struct *find_process_by_pid(pid_t pid)
    
  3. In ./include/linux/init_task.h INIT_TASK macro is added a line to setting the value of invisibility flag creation on “process zero”:
    .invisible		= 0,
    
  4. . dup_task_struct function in ./kernel/fork.c has a new line setting the value of invisibility flag on forked process:
    tsk->invisible = 0;
    
  5. In ./fs/proc/base.c has many additions and modifications where controlling the task structure’s nullity status. It has been added invisibility control of the process.
    ATTENTION: Most of if(task_struct type) check is altered to if(task_struct type && task_struct type->invisible) or another if(task_struct type->invisible) check added. Some of checks didn’t changed. I don’t know how definitely where they are.

     	if(task->invisible)
    		goto out_no_task;
    ---
    < 	if (task) { > 	if (task && !task->invisible) {
    
  6. ./fs/proc/array.c has modifications about adding the invisibility status of a process in /proc/pid/status.
    < 		"Gid:\t%d\t%d\t%d\t%d\n", > 		"Gid:\t%d\t%d\t%d\t%d\n"
    > 		"Invisible:\t%d\n",
    
    < 		cred->gid, cred->egid, cred->sgid, cred->fsgid);
    > 		cred->gid, cred->egid, cred->sgid, cred->fsgid,
    > 		p->invisible);
    

System Call

  1. In order to create our own system call, we defined it in ./arch/x86/include/asm/unistd_32.h as:
    #define __NR_SYSTEM_CALL_NAME	THE_LAST_NUMBER+1
  2. Last number was 336 in my code, and my process name was set_proc_invisibility:

    #define __NR_set_proc_invisibility	337
  3. In order to create our own system call, we defined it in ./include/linux/syscall.h as:
    asmlinkage long sys_set_proc_invisibility(int pid,int status);
  4. In order to create our own system call, we defined it in ./arch/x86/kernel/syscall_table_32.S as:
    .long sys_set_proc_invisibility
  5. We created a new directory (./procinvis) in /usr/src/linux to implement our system call. We added procinvis/ to Makefile. Thereby, gcc will compile ./procinvis/ directory too.
  6. And the system call:

    #include 
    #include 
    #include 
    #include 
    #include 
    
    extern struct task_struct *find_process_by_pid(pid_t pid);
    extern struct rq *task_rq_lock(struct task_struct *p, unsigned long *flags);
    extern inline void task_rq_unlock(struct rq *rq, unsigned long *flags);
    
    static int uid;
    module_param(uid,int,0600);
    
    asmlinkage long sys_set_proc_invisibility(int pid,int status)
    {
    	long retval = 0;
    	if(status != 0 && status != 1)
    	{
    		printk(KERN_ALERT,"INVISIBILITY: Wrong input for the status flag.\n");
    		return -1;
    	}
    
    	struct task_struct *tsk;
    	unsigned long flags;
    	struct rq *rq;
    	tsk = find_process_by_pid((pid_t) pid);
    	rq = task_rq_lock(tsk, &flags);
    	tsk->invisible = status;
    	task_rq_unlock(rq, &flags);
    
    	return retval;
    }
    
  7. To compile our system call the Makefile is:
    obj-y := procinvis.o

Userspace Test Program

To test our system call we have a user space program:
procinvis.h

#include

#define __NR_set_proc_invisibility 337
/*_syscall2( long, set_proc_invisibility, int, pid, int, status);*/

long set_proc_invisibility(int pid, int status){
	return syscall(__NR_set_proc_invisibility,pid,status);
}

procinvis.c

#include 
#include 
#include 
#include 
#include 


extern struct task_struct *find_process_by_pid(pid_t pid);
extern struct rq *task_rq_lock(struct task_struct *p, unsigned long *flags);
extern inline void task_rq_unlock(struct rq *rq, unsigned long *flags);

static int uid;
module_param(uid,int,0600);

asmlinkage long sys_set_proc_invisibility(int pid,int status)
{
	long retval;
	if(status != 0 && status != 1)
	{
		printk(KERN_ALERT,"INVISIBILITY: Wrong input for the status flag.\n");
		return -99;
	}


	struct task_struct *tsk;
	unsigned long flags;
	struct rq *rq;
	tsk = find_process_by_pid((pid_t) pid);
	rq = task_rq_lock(tsk, &flags);
	tsk->invisible = status;
	task_rq_unlock(rq, &flags);

	return retval;
}


Compiling Kernel

To compile the kernel:

make-kpkg -initrd -append-to-version=-custom kernel_image kernel_headers

to recompile the kernel:

cd debian
rm -rf *
cd -
make-kpkg -initrd -append-to-version=-custom kernel_image kernel_headers

And it is installed to system via:

dpkg –i ../linux*.deb

Restart your system and open with your custom kernel:

And the working of our kernel:

If you have any question you can contact me.

My modifications: Process Invisibility Download Link

Your email address will not be published. Required fields are marked *

Time limit is exhausted. Please reload the CAPTCHA.