Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save morkev/fd515a786cde6168eacf034993441dc3 to your computer and use it in GitHub Desktop.

Select an option

Save morkev/fd515a786cde6168eacf034993441dc3 to your computer and use it in GitHub Desktop.
Multi-processed assembly to dynamically respond to multiple HTTP POST requests
.intel_syntax noprefix
.globl _start
.section .text
_start:
# Create socket
mov rdi, 2 # AF_INET
mov rsi, 1 # SOCK_STREAM
mov rdx, 0 # Protocol
mov rax, 41 # socket syscall
syscall
mov rbx, rax # Save socket fd
# Bind socket to port 80
mov rdi, rbx
lea rsi, sa_family_t
mov rdx, 16
mov rax, 49 # bind syscall
syscall
# Listen with backlog of 0
mov rdi, rbx
mov rsi, 0 # Backlog of 0 as specified
mov rax, 50 # listen syscall
syscall
accept_loop:
# Accept connection
mov rdi, rbx
mov rsi, 0
mov rdx, 0
mov rax, 43 # accept syscall
syscall
mov r12, rax # Save client socket fd
# Fork process
mov rax, 57 # fork syscall
syscall
cmp rax, 0
je handle_post # Child process handles POST
# Parent process closes client socket and continues accepting
mov rdi, r12
mov rax, 3 # close syscall
syscall
jmp accept_loop
handle_post:
# Child process closes listening socket
mov rdi, rbx
mov rax, 3 # close syscall
syscall
# Read request
mov rdi, r12
lea rsi, read_buffer
mov rdx, 1024
mov rax, 0 # read syscall
syscall
# Extract filename from POST request
lea rdi, read_buffer
mov rsi, 1 # Get first space
lea rdx, space
call get_nth_substr
mov r13, rax
lea rdi, read_buffer
mov rsi, 2 # Get second space
call get_nth_substr
mov r14, rax
sub r14, 1
# Get filename
mov rdi, r13
mov rsi, r14
lea rdx, file_name_buffer
call write_to_buf
# Create/open file
lea rdi, file_name_buffer
mov rsi, 0x41 # O_WRONLY | O_CREAT
mov rdx, 0777 # Permissions
mov rax, 2 # open syscall
syscall
mov r13, rax
# Find POST data
lea rdi, read_buffer
mov rsi, 1
lea rdx, double_cr_lf
call get_nth_substr
mov rsi, rax
add rsi, 1
# Get data length and write
mov rdi, rsi
call get_len
mov rdx, rax
sub rdx, 1
mov rdi, r13
mov rax, 1 # write syscall
syscall
# Close file
mov rdi, r13
mov rax, 3
syscall
# Send response
mov rdi, r12
lea rsi, write_static
mov rdx, 19
mov rax, 1 # write syscall
syscall
# Close connection
mov rdi, r12
mov rax, 3
syscall
# Exit child
mov rdi, 0
mov rax, 60 # exit syscall
syscall
get_len:
mov rax, 0
get_len_loop:
mov r10, rdi
add r10, rax
mov r10, [r10]
add rax, 1
cmp r10, 0x00
jne get_len_loop
ret
write_to_buf:
write_to_buf_loop:
add rdi, 1
mov r9, [rdi]
mov [rdx], r9
add rdx, 1
cmp rdi, rsi
jne write_to_buf_loop
mov byte ptr [rdx], 0x00
ret
get_nth_substr:
mov rcx, 0
mov r10, rdx
check_character_loop:
mov r9b, [rdi]
cmp r9b, 0x00
je not_enough_occurrences
cmp r9b, byte ptr [r10]
jne character_not_equal
add r10, 1
cmp byte ptr [r10], 0x00
jne after_comparison
mov r10, rdx
add rcx, 1
jmp after_comparison
character_not_equal:
mov r10, rdx
after_comparison:
cmp rcx, rsi
je match
add rdi, 1
jmp check_character_loop
match:
mov rax, rdi
ret
not_enough_occurrences:
mov rax, -1
ret
.section .data
# Network setup for port 80
sa_family_t: .word 2 # AF_INET
bind_port: .word 0x5000 # Port 80 (0x0050)
bind_address: .double 0x00000000 # 0.0.0.0
pad: .byte 0,0,0,0,0,0,0,0
# Buffers and constants
read_buffer: .space 1024
file_name_buffer: .space 1024
file_read_buffer: .space 1024
read_packet_length: .quad 0x0000000000000400
write_static: .string "HTTP/1.0 200 OK\r\n\r\n"
space: .string " "
double_cr_lf: .string "\r\n\r\n"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment