elf helper (linker?) program
This commit is contained in:
parent
79a4c65df3
commit
654c14d92b
148
stages/hex1/elf.asm
Normal file
148
stages/hex1/elf.asm
Normal file
|
|
@ -0,0 +1,148 @@
|
||||||
|
;; Program that takes an output file to which it writes elf64 headers and the contents of a second file which is assumed to be a text section.
|
||||||
|
|
||||||
|
die:
|
||||||
|
mov rax, 60 ; syscall: exit
|
||||||
|
mov rdi, 0 ; status: 0
|
||||||
|
syscall
|
||||||
|
ret
|
||||||
|
|
||||||
|
fopen:
|
||||||
|
mov rax, 2 ; syscall: open
|
||||||
|
mov rsi, 0 ; flags: O_RDONLY
|
||||||
|
mov rdx, 0 ; mode
|
||||||
|
syscall
|
||||||
|
ret
|
||||||
|
|
||||||
|
fopen_write:
|
||||||
|
mov rax, 2 ; syscall: open
|
||||||
|
mov rsi, 0x241 ; flags: O_WRONLY | O_CREAT | O_TRUNC
|
||||||
|
mov rdx, 0o644 ; mode: rw-r--r--
|
||||||
|
syscall
|
||||||
|
ret
|
||||||
|
|
||||||
|
;; rdi: fd
|
||||||
|
;; rsi: buffer
|
||||||
|
fstat:
|
||||||
|
mov rax, 5 ; syscall: fstat
|
||||||
|
syscall
|
||||||
|
ret
|
||||||
|
|
||||||
|
fsize:
|
||||||
|
push rdi
|
||||||
|
push rsi
|
||||||
|
call fstat
|
||||||
|
pop rsi
|
||||||
|
pop rdi
|
||||||
|
mov rax, [rsi + 48] ; st_size
|
||||||
|
ret
|
||||||
|
|
||||||
|
;; rdi: dst
|
||||||
|
;; rsi: src
|
||||||
|
;; rdx: len
|
||||||
|
memcpy:
|
||||||
|
.memcpy_loop:
|
||||||
|
test rdx, rdx
|
||||||
|
jz .memcpy_done
|
||||||
|
mov al, byte [rsi]
|
||||||
|
mov byte [rdi], al
|
||||||
|
inc rsi
|
||||||
|
inc rdi
|
||||||
|
dec rdx
|
||||||
|
jmp .memcpy_loop
|
||||||
|
|
||||||
|
.memcpy_done:
|
||||||
|
ret
|
||||||
|
|
||||||
|
;; variables:
|
||||||
|
;; +0 buffer: [u8; 0x1000]
|
||||||
|
;; +0x1000 bytes_read: u32
|
||||||
|
;; +0x1004 in_size: u32
|
||||||
|
;; +0x1008 in_fd: u32
|
||||||
|
;; +0x100c out_fd: u32
|
||||||
|
;; +0x1010 argc: u32
|
||||||
|
;; +0x1018 argv: *const *const u8
|
||||||
|
|
||||||
|
_start:
|
||||||
|
mov eax, dword [rsp] ; argc
|
||||||
|
lea rbx, [rsp + 8] ; argv
|
||||||
|
sub rsp, 0x4000 ; reserve stack space
|
||||||
|
mov r15, rsp ; r15 = pointer to our state
|
||||||
|
mov dword [r15 + 0x1010], eax ; store argc
|
||||||
|
mov qword [r15 + 0x1018], rbx ; store argv
|
||||||
|
cmp eax, 3
|
||||||
|
jl die
|
||||||
|
|
||||||
|
;; open output file
|
||||||
|
mov rdi, [r15 + 0x1018] ; rdi = argv
|
||||||
|
add rdi, 8 ; rdi = argv[1]
|
||||||
|
mov rdi, [rdi] ; rdi = pointer to argv[1]
|
||||||
|
call fopen_write
|
||||||
|
mov dword [r15 + 0x100c], eax ; store out_fd
|
||||||
|
|
||||||
|
;; open input file and get size
|
||||||
|
mov rdi, [r15 + 0x1018] ; rdi = argv
|
||||||
|
add rdi, 16 ; rdi = argv[2]
|
||||||
|
mov rdi, [rdi] ; rdi = pointer to argv[2]
|
||||||
|
call fopen
|
||||||
|
mov dword [r15 + 0x1008], eax ; store in_fd
|
||||||
|
mov edi, eax ; rdi = in_fd
|
||||||
|
lea rsi, [r15] ; rsi = pointer to statbuf
|
||||||
|
call fsize
|
||||||
|
mov dword [r15 + 0x1004], eax ; store in_size
|
||||||
|
|
||||||
|
;; copy elf header to scratch space
|
||||||
|
mov rdi, 0x400000
|
||||||
|
mov rsi, r15
|
||||||
|
mov rdx, 0x40
|
||||||
|
call memcpy
|
||||||
|
|
||||||
|
;; copy program header to scratch space
|
||||||
|
mov rdi, 0x400040
|
||||||
|
mov rsi, [r15 + 0x40]
|
||||||
|
mov rdx, 0x38
|
||||||
|
call memcpy
|
||||||
|
|
||||||
|
;; write p_filesz and p_memsz to 0x78 + in_size
|
||||||
|
mov rax, 0x78
|
||||||
|
add eax, dword [r15 + 0x1004] ; rax = 0x78 + in_size
|
||||||
|
mov dword [r15 + 0x60], eax ; write p_filesz
|
||||||
|
mov dword [r15 + 0x68], eax ; write p_memsz
|
||||||
|
|
||||||
|
;; write e_entry to point at 0x40 + 0x38 + in_size - 5
|
||||||
|
sub rax, 5
|
||||||
|
mov dword [r15 + 24], eax ; write e_entry
|
||||||
|
|
||||||
|
;; write Ehdr and Phdr to output file
|
||||||
|
mov edi, dword [r15 + 0x100c] ; rdi = out_fd
|
||||||
|
mov rsi, r15 ; rsi = buffer
|
||||||
|
mov rdx, 0x78 ; size of Ehdr + Phdr
|
||||||
|
mov rax, 1 ; syscall: write
|
||||||
|
syscall
|
||||||
|
|
||||||
|
;; copy text section from input file to output file
|
||||||
|
.copy_loop:
|
||||||
|
mov edi, dword [r15 + 0x1008] ; rdi = in_fd
|
||||||
|
mov rsi, r15 ; rsi = pointer to buffer
|
||||||
|
mov rdx, 0x1000 ; rdx = size of buffer
|
||||||
|
mov rax, 0 ; syscall: read
|
||||||
|
syscall
|
||||||
|
test rax, rax
|
||||||
|
jle die
|
||||||
|
mov dword [r15 + 0x1000], eax ; store number of bytes read
|
||||||
|
mov edi, dword [r15 + 0x100c] ; rdi = out_fd
|
||||||
|
mov rsi, r15 ; rsi = pointer to buffer
|
||||||
|
mov edx, dword [r15 + 0x1000] ; rdx = number of bytes read
|
||||||
|
mov rax, 1 ; syscall: write
|
||||||
|
syscall
|
||||||
|
cmp dword [r15 + 0x1000], 0x1000 ; if we read less than 0x1000 bytes, we are done
|
||||||
|
je .copy_loop
|
||||||
|
call die
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
266
stages/hex1/elf.in
Normal file
266
stages/hex1/elf.in
Normal file
|
|
@ -0,0 +1,266 @@
|
||||||
|
; ELF header
|
||||||
|
; e_ident: u128
|
||||||
|
; Magic number: 0x7f454c46 = "\x7fELF"
|
||||||
|
7f 45 4c 46
|
||||||
|
; EI_CLASS: u8 = ELFCLASS64
|
||||||
|
02
|
||||||
|
; EI_DATA: u8 = ELFDATA2LSB
|
||||||
|
01
|
||||||
|
; EI_VERSION: u8 = EV_CURRENT
|
||||||
|
01
|
||||||
|
; EI_OSABI: u8 = ELFOSABI_NONE
|
||||||
|
00
|
||||||
|
; EI_ABIVERSION: u8 = 0
|
||||||
|
00
|
||||||
|
; EI_PAD: [u8; 7]
|
||||||
|
00 00 00 00 00 00 00
|
||||||
|
; e_type: u16 = E_EXEC
|
||||||
|
02 00
|
||||||
|
; e_machine: u16 = EM_X86_64
|
||||||
|
3e 00
|
||||||
|
; e_version: u32 = EV_CURRENT
|
||||||
|
01 00 00 00
|
||||||
|
; e_entry: u64 = 0x400078
|
||||||
|
78 00 40 00 00 00 00 00
|
||||||
|
; e_phoff: u64 = 0x40
|
||||||
|
40 00 00 00 00 00 00 00
|
||||||
|
; e_shoff: u64 = 0x0
|
||||||
|
00 00 00 00 00 00 00 00
|
||||||
|
; e_flags: u32 = 0
|
||||||
|
00 00 00 00
|
||||||
|
; e_ehsize: u16 = 64
|
||||||
|
40 00
|
||||||
|
; e_phentsize: u16 = 56
|
||||||
|
38 00
|
||||||
|
; e_phnum: u16 = 1
|
||||||
|
01 00
|
||||||
|
; e_shentsize: u16 = 0
|
||||||
|
00 00
|
||||||
|
; e_shnum: u16 = 0
|
||||||
|
00 00
|
||||||
|
; e_shstrndx: u16 = 0
|
||||||
|
00 00
|
||||||
|
; End of ELF header
|
||||||
|
;
|
||||||
|
; Program header
|
||||||
|
; p_type: u32 = PT_LOAD
|
||||||
|
01 00 00 00
|
||||||
|
; p_flags: u32 = PF_R | PF_X
|
||||||
|
05 00 00 00
|
||||||
|
; p_offset: u64 = 0
|
||||||
|
00 00 00 00 00 00 00 00
|
||||||
|
; p_vaddr: u64 = 0x400000
|
||||||
|
00 00 40 00 00 00 00 00
|
||||||
|
; p_paddr: u64 = 0x0
|
||||||
|
00 00 00 00 00 00 00 00
|
||||||
|
; p_filesz: u64 = 0x167
|
||||||
|
67 01 00 00 00 00 00 00
|
||||||
|
; p_memsz: u64 = 0x167
|
||||||
|
67 01 00 00 00 00 00 00
|
||||||
|
; p_align: u64 = 0x1000
|
||||||
|
00 10 00 00 00 00 00 00
|
||||||
|
; End of program header
|
||||||
|
;
|
||||||
|
; @die: +0
|
||||||
|
; mov rax, 60 (exit)
|
||||||
|
b8 3c 00 00 00
|
||||||
|
; mov rdi, 0 (exit code)
|
||||||
|
bf 00 00 00 00
|
||||||
|
; syscall
|
||||||
|
0f 05
|
||||||
|
; ret
|
||||||
|
c3
|
||||||
|
;
|
||||||
|
; @fopen:
|
||||||
|
; mov rax, 2 (sys_open)
|
||||||
|
b8 02 00 00 00
|
||||||
|
; mov rsi, 0
|
||||||
|
be 00 00 00 00
|
||||||
|
; mov rdx, 0
|
||||||
|
ba 00 00 00 00
|
||||||
|
; syscall
|
||||||
|
0f 05
|
||||||
|
; ret
|
||||||
|
c3
|
||||||
|
;
|
||||||
|
; fopen_write:
|
||||||
|
; mov rax, 2 (sys_open)
|
||||||
|
b8 02 00 00 00
|
||||||
|
; mov rsi, 0x241 (O_WRONLY | O_CREAT | O_TRUNC)
|
||||||
|
be 41 02 00 00
|
||||||
|
; mov rdx, 0o644 (file mode)
|
||||||
|
ba a4 01 00 00
|
||||||
|
; syscall
|
||||||
|
0f 05
|
||||||
|
; ret
|
||||||
|
c3
|
||||||
|
;
|
||||||
|
; @fstat:
|
||||||
|
; mov rax, 5 (sys_fstat)
|
||||||
|
b8 05 00 00 00
|
||||||
|
; syscall
|
||||||
|
0f 05
|
||||||
|
; ret
|
||||||
|
c3
|
||||||
|
;
|
||||||
|
; @fsize:
|
||||||
|
; push rdi
|
||||||
|
57
|
||||||
|
; push rsi
|
||||||
|
56
|
||||||
|
; call 'fstat
|
||||||
|
e8 f1 ff ff ff
|
||||||
|
; pop rsi
|
||||||
|
5e
|
||||||
|
; pop rdi
|
||||||
|
5f
|
||||||
|
; mov rax, [rsi+48] (st_size)
|
||||||
|
48 8b 46 30
|
||||||
|
; ret
|
||||||
|
c3
|
||||||
|
|
||||||
|
; @memcpy:
|
||||||
|
; test rdx, rdx
|
||||||
|
48 85 d2
|
||||||
|
; jz 'memcpy_exit
|
||||||
|
74 0f
|
||||||
|
; mov al, byte [rsi]
|
||||||
|
8a 06
|
||||||
|
; mov byte [rdi], al
|
||||||
|
88 07
|
||||||
|
; inc rsi
|
||||||
|
48 ff c6
|
||||||
|
; inc rdi
|
||||||
|
48 ff c7
|
||||||
|
; dec rdx
|
||||||
|
48 ff ca
|
||||||
|
; jmp 'memcpy
|
||||||
|
eb ec
|
||||||
|
; @memcpy_exit:
|
||||||
|
c3
|
||||||
|
;
|
||||||
|
; @_start:
|
||||||
|
; mov eax, dword [rsp] (argc)
|
||||||
|
8b 04 24
|
||||||
|
; lea rbx, [rsp+8] (argv)
|
||||||
|
48 8d 5c 24 08
|
||||||
|
; sub rsp, 0x4000
|
||||||
|
48 81 ec 00 40 00 00
|
||||||
|
; mov r15, rsp
|
||||||
|
49 89 e7
|
||||||
|
; mov dword [r15+0x1010], eax (store argc)
|
||||||
|
41 89 87 10 10 00 00
|
||||||
|
; mov qword [r15+0x1018], rbx (store argv)
|
||||||
|
49 89 9f 18 10 00 00
|
||||||
|
; cmp eax, 3
|
||||||
|
83 f8 03
|
||||||
|
; jl 'die
|
||||||
|
0f 8c 7b ff ff ff
|
||||||
|
;
|
||||||
|
; mov rdi, qword [r15+0x1018] (argv)
|
||||||
|
49 8b bf 18 10 00 00
|
||||||
|
; add rdi, 8 (argv[1])
|
||||||
|
48 83 c7 08
|
||||||
|
; mov rdi, [rdi] (argv[1])
|
||||||
|
48 8b 3f
|
||||||
|
; call 'fopen_write
|
||||||
|
e8 87 ff ff ff
|
||||||
|
;
|
||||||
|
; mov dword [r15+0x101c], eax (store file descriptor)
|
||||||
|
41 89 87 0c 10 00 00
|
||||||
|
; mov rdi, qword [r15+0x1018] (argv)
|
||||||
|
49 8b bf 18 10 00 00
|
||||||
|
; add rdi, 16 (argv[2])
|
||||||
|
48 83 c7 10
|
||||||
|
; mov rdi, [rdi] (argv[2])
|
||||||
|
48 8b 3f
|
||||||
|
; call 'fopen
|
||||||
|
e8 5b ff ff ff
|
||||||
|
;
|
||||||
|
; mov dword [r15+0x1008], eax (store file descriptor)
|
||||||
|
41 89 87 08 10 00 00
|
||||||
|
; mov edi, eax (fd)
|
||||||
|
89 c7
|
||||||
|
; lea rsi, [r15]
|
||||||
|
49 8d 37
|
||||||
|
; call 'fsize
|
||||||
|
e8 76 ff ff ff
|
||||||
|
;
|
||||||
|
; mov dword [r15+0x1004], eax (store file size)
|
||||||
|
41 89 87 04 10 00 00
|
||||||
|
; mov edi, 0x400000
|
||||||
|
bf 00 00 40 00
|
||||||
|
; mov rsi, r15
|
||||||
|
4c 89 fe
|
||||||
|
; mov edx, 0x40 (size)
|
||||||
|
ba 40 00 00 00
|
||||||
|
; call 'memcpy
|
||||||
|
e8 6b ff ff ff
|
||||||
|
;
|
||||||
|
; mov edi, 0x400040
|
||||||
|
bf 40 00 40 00
|
||||||
|
; mov rsi, [r15+0x40]
|
||||||
|
49 8b 77 40
|
||||||
|
; mov edx, 0x38 (size)
|
||||||
|
ba 38 00 00 00
|
||||||
|
; call 'memcpy
|
||||||
|
e8 58 ff ff ff
|
||||||
|
;
|
||||||
|
; mov eax, 0x78
|
||||||
|
b8 78 00 00 00
|
||||||
|
; add eax, dword [r15+0x1004] (file size)
|
||||||
|
41 03 87 04 10 00 00
|
||||||
|
; mov dword [r15+0x60], eax (store file end)
|
||||||
|
41 89 47 60
|
||||||
|
; mov dword [r15+0x68], eax (store file end)
|
||||||
|
41 89 47 68
|
||||||
|
;
|
||||||
|
; sub rax, 5
|
||||||
|
48 83 e8 05
|
||||||
|
; mov dword [r15+0x18], eax (store file end - 5)
|
||||||
|
41 89 47 18
|
||||||
|
;
|
||||||
|
; mov edi, dword [r15+0x100c] (fd)
|
||||||
|
41 8b bf 0c 10 00 00
|
||||||
|
; mov rsi, r15
|
||||||
|
4c 89 fe
|
||||||
|
; mov edx, 0x78 (size)
|
||||||
|
ba 78 00 00 00
|
||||||
|
; mov eax, 1 (sys_write)
|
||||||
|
b8 01 00 00 00
|
||||||
|
; syscall
|
||||||
|
0f 05
|
||||||
|
; @write_loop:
|
||||||
|
; mov edi, dword [r15+0x1008] (fd)
|
||||||
|
41 8b bf 08 10 00 00
|
||||||
|
; mov rsi, r15
|
||||||
|
4c 89 fe
|
||||||
|
; mov edx, 0x1000 (size)
|
||||||
|
ba 00 10 00 00
|
||||||
|
; mov eax, 0 (sys_read)
|
||||||
|
b8 00 00 00 00
|
||||||
|
; syscall
|
||||||
|
0f 05
|
||||||
|
; test rax, rax
|
||||||
|
48 85 c0
|
||||||
|
; jle 'die
|
||||||
|
0f 8e c0 fe ff ff
|
||||||
|
;
|
||||||
|
; mov dword [r15+0x1000], eax (store bytes read)
|
||||||
|
41 89 87 00 10 00 00
|
||||||
|
; mov edi, dword [r15+0x100c] (fd)
|
||||||
|
41 8b bf 0c 10 00 00
|
||||||
|
; mov rsi, r15
|
||||||
|
4c 89 fe
|
||||||
|
; mov edx, dword [r15+0x1000] (bytes read)
|
||||||
|
41 8b 97 00 10 00 00
|
||||||
|
; mov eax, 1 (sys_write)
|
||||||
|
b8 01 00 00 00
|
||||||
|
; syscall
|
||||||
|
0f 05
|
||||||
|
; cmp dword [r15+0x1000], 0x1000
|
||||||
|
41 81 bf 00 10 00 00 00 10 00 00
|
||||||
|
; jz 'write_loop
|
||||||
|
74 b5
|
||||||
|
; call 'die
|
||||||
|
e8 8f fe ff ff
|
||||||
Loading…
Reference in a new issue