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.
- . 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; };
- In ./kernel/sched.c, we altered
task_rq_lock
,task_rq_unlock
andfind_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)
- 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,
- .
dup_task_struct
function in ./kernel/fork.c has a new line setting the value of invisibility flag on forked process:tsk->invisible = 0;
- 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 ofif(task_struct type)
check is altered toif(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) {
- ./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
- 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
- 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);
- 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
- 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.
- To compile our system call the Makefile is:
obj-y := procinvis.o
Last number was 336 in my code, and my process name was set_proc_invisibility
:
#define __NR_set_proc_invisibility 337
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;
}
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
wow, great tip.
çok güzel paylaşım. Teşekkürler.