.global _start .data v_elf_header: .byte 0x7f # Magic Number .ascii "ELF" # .byte 0x2 # 64-Bit .byte 0x1 # little-endian .byte 0x1 # ELFv1 .byte 0x0 # System V ABI .quad 0x0 # .hword 0x02 # Executable .hword 0x3e # AMD x86-64 .int 0x1 # ELFv1 .quad 0x401000 # Entry .quad 0x40 # Program Header Offset .quad 0x100 # TODO: Section Header Offset .int 0x0 # .hword 0x40 # ELF Header Size .hword 0x38 # Program Header Table Entry Size .hword 0x3 # TODO: Number Of Entries in Program Header Table .hword 0x40 # Section Header Table Entry Size .hword 0x3 # TODO: Number Of Entries in Section Header Table .hword 0x2 # TODO: Index of Section Header Table Entry containing section names v_usage_message: .asciz "bfc [input file] [output file]\n" v_input_fd: .int 0x0 v_output_fd: .int 0x0 v_buffer_start: .quad 0x0 v_buffer_end: .quad 0x0 v_buffer_cursor: .quad 0x0 .text _start: mov %rsp, %rbp call f_check_args call f_open_files call f_init_buffer mov $v_buffer_cursor, %rbx mov (%rbx), %rsi add $0x300, %rsi mov %rsi, (%rbx) call f_check_buffer mov $v_buffer_cursor, %rsi mov (%rbx), %rsi add $0x300, %rsi mov %rsi, (%rbx) call f_check_buffer # ---- mov $1, %rax mov %rcx, %rdi mov $v_elf_header, %rsi mov $0x40, %rdx syscall # ---- call f_close_files mov $0, %rdi jmp f_exit f_exit: mov $60, %rax syscall f_check_args: mov (%rbp), %rax cmp $3, %rax je l_check_args_success mov $1, %rax mov $2, %rdi mov $v_usage_message, %rsi mov $32, %rdx syscall mov $-1, %rdi jmp f_exit l_check_args_success: ret f_open_files: mov $2, %rax mov 16(%rbp), %rdi mov $0, %rsi mov $0, %rdx syscall mov $v_input_fd, %rbx mov %eax, (%rbx) mov $2, %rax mov 24(%rbp), %rdi mov $0x41, %rsi mov $0744, %rdx syscall mov $v_output_fd, %rbx mov %eax, (%rbx) ret f_close_files: mov $3, %rax mov %rbx, %rsi syscall mov $3, %rax mov %rcx, %rsi syscall ret f_init_buffer: mov $12, %rax mov $0, %rdi syscall mov $v_buffer_start, %rbx mov %rax, (%rbx) mov $v_buffer_end, %rbx mov %rax, (%rbx) mov $v_buffer_cursor, %rbx mov %rax, (%rbx) /* * We directly skip to f_resize_buffer * since we want to resize it to a usable amount */ f_resize_buffer: mov $12, %rax mov $v_buffer_end, %rbx mov (%rbx), %rdi add $0x400, %rdi syscall mov %rax, (%rbx) ret /* %rsi = needed end */ f_check_buffer: mov $v_buffer_end, %rbx mov (%rbx), %rax cmp %rax, %rsi jl l_check_buffer_large_enough call f_resize_buffer l_check_buffer_large_enough: ret