linux创建隐藏进程6,修改linux内核达到隐藏进程目的(2.6.28)

要求:

高级操作系统与分布式系统作业

ps和top命令列出了unix中当前所有进程的相关信息,作业要求在linux中增加两个系统调用,功能如下:

hide():执行此系统调用后,隐藏当前进程,即当前进程不能够被ps和top命令查看到。

unhide():执行此系统调用后,取消隐藏当前进程,即当前进程恢复正常,能够被ps和top命令查看到。

解题思路:

Ps命令和top命令从/proc文件系统中读取进程信息并显示出来。因此,如果一个进程的进程号没有在/proc文件系统中反映出来,则这个进程被“隐藏”了,“隐藏”进程在ps或top命令的输出不出现。

2。修改linux的进程控制块task_struts,在进程控制块中增加一个字段:

int hide;

hide的值为1时,表示该进程被隐藏;为0时,表示该进程不被隐藏。

3。修改创建进程的相关代码,在进程创建时,置hide为0;即进程在初始创建时(默认)不被隐藏。

4。在系统中增加系统调用hide(),其功能为:

1)将进程控制块中的hide置1;

2)删除/proc文件系统中该进程的相关目录项;

5。在系统中增加系统调用unhide(),其功能为:

1)将进程控制块中的hide清0;

2)增加/proc文件系统中该进程的相关目录项

具体做法:(实验内核版本2.6.28,)

跟踪内核可知,proc目录下进程号目录是动态生成的,是在每次readdir,getdents时动态生成,所以从某种意义上说增加或删除/proc文件系统中该进程的相关目录项这种说法是不正确的。proc目录内容的填充函数是proc_pid_readdir(fs/proc/base.c)

int proc_pid_readdir(struct file * filp, void * dirent, filldir_t filldir)  //内核源码,修改前

{

unsigned int nr = filp->f_pos - FIRST_PROCESS_ENTRY;

struct task_struct *reaper = get_proc_task(filp->f_path.dentry->d_inode);

struct tgid_iter iter;

struct pid_namespace *ns;

if (!reaper)

goto out_no_task;

for (; nr < ARRAY_SIZE(proc_base_stuff); filp->f_pos++, nr++) { //这个for,填充self目录

const struct pid_entry *p = &proc_base_stuff[nr];

if (proc_base_fill_cache(filp, dirent, filldir, reaper, p) < 0)

goto out;

}

ns = filp->f_dentry->d_sb->s_fs_info;

iter.task = NULL;

iter.tgid = filp->f_pos - TGID_OFFSET;

for (iter = next_tgid(ns, iter);

iter.task;

iter.tgid += 1, iter = next_tgid(ns, iter)) {  //这个for,根据系统内进程动态添加子进程号目录,也正是我们需要修改的函数

filp->f_pos = iter.tgid + TGID_OFFSET;

if (proc_pid_fill_cache(filp, dirent, filldir, iter) < 0) {

put_task_struct(iter.task);

goto out;

}

} filp->f_pos = PID_MAX_LIMIT + TGID_OFFSET;

out:

put_task_struct(reaper);

out_no_task:

return 0;

}

将proc_pid_readdir函数中的for循环修改为

for (iter = next_tgid(ns, iter);

iter.task;

iter.tgid += 1, iter = next_tgid(ns, iter)) {  //这个for,根据系统内进程动态添加子进程号目录,也正是我们需要修改的函数

if(!iter.task->hide){

filp->f_pos = iter.tgid + TGID_OFFSET;

if (proc_pid_fill_cache(filp, dirent, filldir, iter) < 0) {

put_task_struct(iter.task);

goto out;

}

}

}

修改task_struct 添加hide字段(include/linux/sched.h)

struct task_struct{

...//现有字段

int hide;//添加hide字段,切忌不要在最开始添加,因为开始的字段的偏移量已固定,内核中其他部分已直接引用,如果在最开始添加,将导致现有代码不能正常工作

}

修改进程创建代码,初始化时置hide字段为0,修改copy_process函数(kernel/fork.c)

p = dup_task_struct(current);

if (!p)

goto fork_out;

p->hide=0;//添加

rt_mutex_init_task(p);

最后一步就是添加系统调用了,

修改kernel/sys.c

添加

asmlinkage long sys_hide()

{

current->hide=1;

return 0;

}

asmlinkage long sys_unhide()

{

current->hide=0;

return 0;

}

修改arch/x86/asm/include/unistd_32.h

#define __NR_inotify_init1 332

#define __NR_hide 333

#define __NR_unhide 334

#ifdef __KERNEL__

修改arch/x86/kernel/syscall_table_32.s

.long sys_dup3   /* 330 */

.long sys_pipe2

.long sys_inotify_init1

.long sys_hide

.long sys_unhide

重新编译内核...OK....

cfe6b55c0706d4057c0dbb5a9b6d4f0f.gif

实验验证:

1 test_hide.c

#include

int main(){

int pid=getpid();

char command[80];

sprintf(command,"ps aux|grep %d\n",pid);

printf("-------------------------------\n");

system(command);

printf("-------------------------------\n");

asm volatile(\

"int $0x80"\

::"a"(333)); // 执行333号系统调用即sys_hide

system(command);

asm volatile(\

"int $0x80"\

::"a"(334));

printf("-------------------------------\n");

system(command);

printf("-------------------------------\n");

return 0;

}

2 运行,查看实验结果

e5bf85d2ebeb88ecf752e097d7d39aeb.png

相关资源:Linux 进程隐藏
表情包
插入表情
评论将由博主筛选后显示,对所有人可见 | 还能输入1000个字符
相关推荐
©️2020 CSDN 皮肤主题: 游动-白 设计师:白松林 返回首页