Skip to content

Instantly share code, notes, and snippets.

@rday
Created July 27, 2015 04:24
Show Gist options
  • Save rday/d072fe3ab393fd24eae7 to your computer and use it in GitHub Desktop.
Save rday/d072fe3ab393fd24eae7 to your computer and use it in GitHub Desktop.
;NASM=nasm
;LD=ld
;LIBS=-lc
;LD_INCLUDES=-I/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
;
;
;echoserver: echoserver.o
; ${LD} ${LIBS} ${LD_INCLUDES} -o echoserver echoserver.o
;
;echoserver.o: echoserver.s
; ${NASM} -f elf64 echoserver.s
;
;clean:
; rm -f echoserver.o echoserver
bits 64
section .data
welcome db 'Welcome to the echo server', 10, 0
success db 'Success', 10, 0
got_one db 'Got one! %x', 10, 0
socket_error db 'Error creating socket: %x', 10, 0
bind_error db 'Error binding socket: %x', 10, 0
listen_error db 'Error listening socket: %x', 10, 0
read_error db 'Read failed: %x', 10, 0
section .text
global _start
extern printf, exit, malloc, free, memset
handle_connections:
push rbp
mov rbp, rsp
sub rsp, 0x12
; -0x4 listening socket
; -0x8 connected socket
; -0x10 address of recv buffer
; -0x12 loop counter
mov [rbp-4], edi ; Save listening socket
mov rdi, 256 ; Allocate our receive buffer
call malloc
mov [rbp-0x10], rax
mov cx, word 3 ; Do this 3 times
_get_conns:
mov [rbp-0x12], cx ; Save the current loop counter
mov rdi, [rbp-4] ; Accept a new connection
xor esi, esi
xor edx, edx
mov rax, 43
syscall
mov [rbp-0x8], eax ; Save connected socket
lea rdi, [rel got_one]
mov rsi, rax
xor eax, eax
call printf
_read_data:
mov rdi, [rbp-0x10] ; Zero out our read buffer
xor esi, esi
mov edx, 256
call memset
mov rdi, [rbp-0x8] ; Read into our buffer
mov rsi, [rbp-0x10]
mov rdx, 255
xor eax, eax
syscall
push rax
mov edx, eax ; Dump our buffer back
mov eax, 1
syscall
pop rax
cmp eax, 0
jg _read_data
mov rdi, [rbp-0x8]
mov eax, 3 ; And close the connection
syscall
xor ecx, ecx
mov cx, [rbp-0x12]
loop _get_conns
jmp _handle_connections_done
_handle_connections_done:
mov rdi, [rbp-0x10] ; Free our receive buffer
call free
add rsp, 0x12 ; Clean up our frame
pop rbp
ret
_start:
push rbp
mov rbp, rsp
sub rsp, 0x14
; -0x4 socket descriptor
; -0x14 struct sockaddr
; 0x14 sin_family
; 0x12 sin_port
; 0x10 sin_addr
; 0xc sa_data
lea rdi, [rel welcome]
xor eax, eax
call printf
mov edi, 2 ; Create our socket
mov esi, 1 ; AF_INET, IPPROTO_TCP, SOCK_STREAM
mov edx, 6
mov rax, 41
syscall
mov [rbp-4], eax ; Die if it didnt work
cmp eax, -1
js _bad_socket
mov [rbp-0x14], word 2 ; AF_INET
mov [rbp-0x12], word 0x1111 ; Port 4369
mov [rbp-0x10], dword 0x0100007f ; Localhost
mov rdi, [rbp-4] ; Bind to the address
mov rsi, rbp
sub rsi, 0x14
mov rdx, 0x10
mov rax, 49
syscall
cmp eax, -1
js _bad_bind
mov rdi, [rbp-4] ; Listen on the bound port
mov rsi, 2
mov rax, 50
syscall
cmp eax, -1
js _bad_listen
mov edi, [rbp-4]
call handle_connections
lea rdi, [rel success]
xor eax, eax
call printf
jmp _start_done
; Handle all the error conditions we
; might hit while setting up the socket
_bad_socket:
lea edi, [rel socket_error]
jmp _show_error
_bad_bind:
lea edi, [rel bind_error]
jmp _show_error
_bad_listen:
lea edi, [rel listen_error]
_show_error:
mov esi, [rbp-4]
mov eax, 0
call printf
mov edi, [rbp-4]
neg edi
_start_done:
call exit ; Exit code should be set by caller
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment