[bits 64]
file_load_va: equ 4096 * 40
db 0x7f, 'E', 'L', 'F'
db 2
db 1
db 1
db 0
; We'll overwrite the EABI field + 7 bytes padding with our first 8 bytes of
; code. (I checked ahead of time that these instructions take exactly 8 bytes.)
entry_point:
xor eax, eax
inc eax
mov edi, eax
; Skip to the next place we can clobber with our code, since we can't clobber
; the next field (the ELF type).
jmp code_chunk_2
dw 2
dw 0x3e
dd 1
dq entry_point + file_load_va
dq program_headers_start
; We'll next overwrite the 8-byte section header offset field, as well as the
; 4-byte "flags" field that follows it.
code_chunk_2:
mov esi, file_load_va + message
xor edx, edx
mov dl, message_length
; Jump to the final chunk of code, and add one byte of padding to fill up the
; 12th byte of the two fields that we are overwriting.
jmp code_chunk_3
db 0
dw 64
dw 0x38
dw 1
dw 0x40
dw 0
dw 0
program_headers_start:
dd 1
dd 5
dq 0
dq file_load_va
; We'll overwrite the 8-byte "physical address" field in the program header
; with our final 8 bytes of code. These four instructions take exactly 8 bytes.
code_chunk_3:
syscall
mov al, 60
xor edi, edi
syscall
dq file_end
dq file_end
; We can clobber the final 8-byte "alignment" field in the program header, and
; we'll overwrite it with the first 8 bytes of our "Hello, world!" string.
message: db `Hello, world!\n`
message_length: equ $ - message
file_end: