進程隱藏系統調用

來源:互聯網
上載者:User

標籤:blog   http   io   os   使用   ar   strong   for   檔案   

一、實驗內容

    實驗3:Linux進程管理及其擴充

1、閱讀並分析Linux核心原始碼,瞭解進程式控制制塊、進程隊列等資料結構;

2. 實現一個系統調用,使得可以根據指定的參數隱藏進程,使使用者無法使用ps或top觀察到進程狀態。具體要求如下:

(1)實現系統調用int hide(pid_t pid, int on),在進程pid有效前提下,如果on置1,進程被隱藏,使用者無法通過ps或top觀察到進程狀態;如果on置0且此前為隱藏狀態,則恢複正常狀態。

(2)考慮許可權問題,只有根使用者才能隱藏進程。

(3)設計一個新的系統調用int hide_user_processes(uid_t uid, char *binname),參數uid為使用者ID號,當binname參數為NULL時,隱藏該使用者的所有進程;否則,隱藏二進位映像名為binname的使用者進程。該系統調用應與hide系統調用共存。

(4)在/proc目錄下建立一個檔案/proc/hidden,該檔案可讀可寫,對應一個全域變數hidden_flag,當hidden_flag為0時,所有進程都無法隱藏,即便此前進程被hide系統調用要求隱藏。只有當hidden_flag為1時,此前通過hide調用要求被屏蔽的進程才隱藏起來。

(5)在/proc目錄下建立一個檔案/proc/hidden_process,該檔案的內容包含所有被隱藏進程的pid,各pid之間用空格分開。

二、實驗目的

通過實驗,加深理解進程式控制制塊、進程隊列等概念,瞭解進程管理的具體實施方法。

三、設計思路和關鍵代碼

特色功能:

1、進程按照pid、uid、進程名進行隱藏和恢複

2、實現了動態模組載入和核心靜態編譯兩種方式產生proc檔案

3、編寫了測試程式

(1)修改進程式控制制塊(相當於PCB)的資料結構,增加cloak參數,1表示該進程隱藏。在使用ps或者top指令的時候,事實上也就是系統調用,所以要在顯示進程的系統調用的地方按照cloak參數進行過濾。

A、Include/linux/sched.h檔案中儲存進程式控制制塊(struct task_struct)。

 

B、首先要在進程建立的時候對cloak進行初始化,這裡預設初始化為0,表示不隱藏。

fork系統調用的實現代碼在kernel/fork.c中,具體實現的主要函數為do_fork,do_fork中調用copy_process函數建立子進程,建議將初始化cloak的代碼添加在copy_process函數中。

 

C、然後,建立hide系統調用,這裡不再像實驗2一樣建立檔案,而是直接在fs/proc/base.c中添加。通過pid擷取進程task_struct的核心功能為find_task_by_pid。在隱藏後最好調用函數proc_flush_task來清空VFS層的緩衝,解除已有的dentry項。

 

修改proc_pid_readdir函數(在fs/proc/base.c檔案中)。其中使用for迴圈遍曆進程,在遍曆過程中添加判斷,過濾掉被隱藏的進程。

修改proc_pid_lookup函數,在進程尋找完成前過濾掉被隱藏的進程。

(2)考慮許可權時,需要修改cloak的hide系統調用中增加對許可權的判斷,使用全域變數current->uid擷取目前使用者許可權,值為0代表root使用者。

(3)int hide_user_processes(uid_t uid, char *binname),系統調用按照uid或者uid和進程名對進程進行隱藏的系統調用。在fs/proc/base.c添加系統調用。

 

(4)在/proc目錄下建立一個檔案/proc/hidden,該檔案可讀可寫,對應一個全域變數hidden_flag,當hidden_flag為0時,所有進程都無法隱藏,即便此前進程被hide系統調用要求隱藏。只有當hidden_flag為1時,此前通過hide調用要求被屏蔽的進程才隱藏起來。

這個hidden_flag相當於更進階別的控制,當其為0時,仍然可以對cloak操作,但是隱藏的作用失效。

實現proc檔案的建立和讀寫,可以直接寫在核心中也可以通過動態載入模組的方式實現。這裡兩種都做介紹:

  核心中建立proc檔案方式:

A、 首先在fs/proc/proc_misc.c檔案中聲明全域變數,EXPORT_SYMBOL()函數可以使該變數在整個核心中可見。使用時只要extern int hidden_flag;即可訪問同一變數。

 

B、 proc檔案系統在初始化函數proc_root_init中會調用proc_misc_init函數,此函數用於建立/proc根目錄下的檔案,那麼將建立hidden檔案的代碼插入到此函數中就可以在proc初始化時得到執行。(在fs/proc/proc_misc.c檔案中)

 

其中proc_read_hidden和proc_write_hidden分別是對hidden檔案讀寫時的回呼函數。

即當使用者讀取hidden檔案時,返回全域變數hidden_flag的值;

即當使用者寫入hidden檔案時,修改全域變數hidden_flag的值;

這樣就可以實現檔案的值和全域變數實現同步。達到使用者態對核心進行設定的目的。

 

C、 修改proc_pid_readdir函數和proc_pid_lookup函數(在fs/proc/base.c檔案中),增加對hidden_flag的判斷邏輯。

 

proc_pid_lookup:

 

proc_pid_readdir:

 

動態載入模組方式:

A、 只需要在核心fs/proc/proc_misc.c檔案中,添加全域變數

 

B、 建立一個動態模組檔案hide_module.c

在其初始化函數init_hide(void)中編寫:

 

在其關閉函數exit_hide(void)中編寫:

 

C、 將這兩個函數綁定為初始化和退出函數

 

D、 讀寫檔案的回呼函數

 

(5)在/proc目錄下建立一個檔案/proc/hidden_process,該檔案的內容包含所有被隱藏進程的pid,各pid之間用空格分開。那麼也可以分為靜態核心和動態模組兩種實現方式。

核心中建立proc檔案方式:

A、proc檔案系統在初始化函數proc_root_init中會調用proc_misc_init函數,此函數用於建立/proc根目錄下的檔案,那麼將建立hidden檔案的代碼插入到此函數中就可以在proc初始化時得到執行。(在fs/proc/proc_misc.c檔案中)

 

B、由於這個檔案只需要使用者讀取,所以唯寫讀操作的回呼函數即可:

 

這裡需要注意的是,page即為返回給使用者的字串,這個回呼函數的傳回值,為這個字串的長度。

動態載入模組方式:

A、 與hidden檔案的動態載入模組方式相似

在其初始化函數init_hide(void)中編寫:

 

在其關閉函數exit_hide(void)中編寫:

 

B、 其讀操作回呼函數為:

 

四、主要資料結構及其說明task_struct資料結構說明

源自:

http://www.baidu.com/link?url=SO-vtkUs6iRdOHI9se20ZDyI8zjNisNDVxeW7ccNtCfx3YZbVlQFptbKekoIcG9zyDe0PuRvvV7yNn-5zc46_q

proc檔案操作說明建立proc檔案

struct proc_dir_entry * hidefile = create_proc_entry("hidden",0644,NULL);

1、  第一個參數是檔案名稱

2、  第二個參數是檔案的讀寫權限

3、  第三個參數是路徑,因為在proc檔案的根目錄所以為NULL

然後綁定讀寫回呼函數:

hidefile->read_proc = proc_read_hidden;// call back : read

hidefile->write_proc = proc_write_hidden;// call back : write

也可以採用以下方式建立並綁定回呼函數:

struct proc_dir_entry * hideprocessfile = create_proc_read_entry("hidden_process",

                                                                                    0444,

                                                                                    NULL,

                                                                                    proc_read_hidden_process,

                                                                                    NULL);

讀proc檔案

proc檔案不能像普通檔案一樣開啟然後閱讀,需使用如下指令

cat < hidden

使用如下指令寫入檔案

echo “1” > hidden

載入動態模組

在載入模組的目錄下編寫Makefile檔案,然後編譯

$ make                                                                                                                                                                          

進入到root使用者下,載入模組

# insmod hide_module.ko                                                         

卸載模組

# rmmod hide_module                                                                              

五、來源程式動態載入模組hide_module.h
#include<linux/init.h>#include<linux/module.h>#include <linux/fs.h>#include <asm/unistd.h>#include <asm/uaccess.h>#include<linux/proc_fs.h>#include<linux/sched.h>#include<linux/proc_fs.h>#include<linux/slab.h>#include <asm/uaccess.h>MODULE_LICENSE("GPL");extern int hidden_flag;static int proc_read_hidden(char* page,char**start,off_t off,int count,int *eof,void *data){         // hidden ‘s read callback function         int length;         length = sprintf(page,"%d",hidden_flag);//before user read this file, we write the ‘hidden_flag‘ to the file         return length;} static int proc_write_hidden(struct file * file,const char *buffer,unsigned long count,void *data){         // hidden ‘s write callback function         hidden_flag = buffer[0]-‘0‘;//before user write this file , we catch the user‘s input and modify the ‘hidden_flag‘         return count;}static int proc_read_hidden_process(char* page,char**start,off_t off,int count,int *eof,void *data){         // hidden_process ‘s read callback function         struct task_struct *task=NULL;         int num = 0;         for_each_process(task){             if(task->cloak==1){                   sprintf(page+num,"%-4d ",task->pid);                   num+=5;             }         }         return num-5;}static int init_hide(void){         // init module -> create proc file (hidden and hidden_process)         struct proc_dir_entry * hidefile = create_proc_entry("hidden",0644,NULL);// create hidden file and its privilage is read&write         hidefile->read_proc = proc_read_hidden;// call back : read         hidefile->write_proc = proc_write_hidden;// call back : write          struct proc_dir_entry * hideprocessfile = create_proc_read_entry("hidden_process",                                                                                    0444,                                                                                    NULL,                                                                                    proc_read_hidden_process,                                                                                    NULL);              printk("<0>""hidden file ok\n");         return 0;}static void exit_hide(void){         // delete proc file         remove_proc_entry("hidden",NULL);         remove_proc_entry("hidden_process",NULL);         printk("<0>""hidden file close\n");         return;}module_init(init_hide);module_exit(exit_hide);

  

動態載入模組的Makefile
ifneq ($(KERNELRELEASE),)         obj-m:=hide_module.oelse         KDIR:=/lib/modules/$(shell uname -r)/build         PWD:=$(shell pwd)default:         $(MAKE) -C $(KDIR) M=$(PWD) modulesclean:         $(MAKE) -C $(KDIR) M=$(PWD) cleanEndif

  

測試程式
#include<sys/syscall.h>#include<unistd.h>#include<stdio.h>#include<stdlib.h>int main(){         int func=0;         int pid;         int on;         char name[200];         int uid;         while(1){         printf("###please select test function:\n0:my system call\n1:hide\n2hide_process by uid\n3hide_process by name&uid\n4:exit\n");         scanf("%d",&func);         switch(func){         case 0:                   syscall(320);                   break;         case 1:                   printf("input: pid on\n");                   scanf("%d %d",&pid,&on);                   syscall(321,pid,on);                  break;         case 2:                   printf("input: uid on\n");                   scanf("%d %d",&uid,&on);                   syscall(322,uid,NULL,on);                   break;               case 3:                   printf("input: uid on name\n");                   scanf("%d %d %s",&uid,&on,&name);                   syscall(322,uid,name,on);                   break;         default:                   return 0;                 }         }                 return 0;}

進程隱藏系統調用

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.