flat assembler
Message board for the users of flat assembler.
![]() |
Author |
|
reyuki 26 Jan 2025, 13:21
I tried to write an ELF executable from scratch and use this example as reference
however, my program encounter a segfault in the loader (ld-linux.so), and there's a post that mention the same case and the cause is alignment, which previously (before getting involved with the loader and shared lib stuff) I didn't pay attention because it runs without encounter any segfault (probably because it was statically linked?) my question is, why linux only force alignment when the program was dynamically linked? and how to make sure that the ELF program is properly aligned? I'm confused with the ELF standard specification and not quite understand what it means: Quote:
the paragraph is too academic for me personally, if I specify p_align to 0x100000 (like the reference's example) at PT_LOAD entry, how much bytes/padding should I add to meet alignment requirement in the _start section? the assembly code: Code: use64 BASE=0x400000 OFFSETOF equ -BASE+ ELF64_PHEADER_ENTRY_SZ = 56 org BASE Elf64_Ehdr: db 0x7F, "ELF", 2, 1, 1 ; e_ident[...] = 7 bytes times 9 db 0 ; e_ident[EI_PAD] = 9 bytes dw 2 ; e_type ET_EXEC = 2 bytes dw 0x3e ; e_machine AMD x86-64 = 2 bytes dd 1 ; e_version = 4 bytes dq _start ; e_entry entry point = 8 bytes dq OFFSETOF Elf64_Phdr ; e_phoff = 8 bytes dq 0 ; e_shoff = 8 bytes dd 0 ; e_flags = 4 bytes dw Elf64_Ehdr.SIZE ; e_ehsize = 2 bytes dw ELF64_PHEADER_ENTRY_SZ ; e_phentsize = 2 bytes dw Elf64_Phdr.SIZE/ELF64_PHEADER_ENTRY_SZ ; e_phnum = 2 bytes dw 0 ; e_shentsize = 2 bytes dw 0 ; e_shnum = 2 bytes dw 0 ; e_shstrndx = 2 bytes ; total = 64 bytes .SIZE = $-Elf64_Ehdr Elf64_Phdr: dd 3 ; p_type PT_INTERP = 4 bytes dd 4 ; p_flags RO = 4 bytes dq OFFSETOF _interpreter_name_ ; p_offset = 8 bytes dq _interpreter_name_ ; p_vaddr = 8 bytes dq 0 ; p_paddr = 8 bytes dq _interpreter_name_.SIZE ; p_filesz = 8 bytes dq _interpreter_name_.SIZE ; p_memsz = 8 bytes dq 0 ; p_align = 8 bytes dd 2 ; p_type PT_DYNAMIC = 4 bytes dd 4 ; p_flags RO = 4 bytes dq OFFSETOF DYNAMIC ; p_offset = 8 bytes dq DYNAMIC ; p_vaddr = 8 bytes dq 0 ; p_paddr = 8 bytes dq DYNAMIC.SIZE ; p_filesz = 8 bytes dq DYNAMIC.SIZE ; p_memsz = 8 bytes dq 0 ; p_align = 8 bytes dd 1 ; p_type PT_LOAD = 4 bytes dd 7 ; p_flags RWX = 4 bytes dq OFFSETOF _start ; p_offset = 8 bytes dq _start ; p_vaddr = 8 bytes dq 0 ; p_paddr = 8 bytes dq FILE.SIZE ; p_filesz = 8 bytes dq FILE.SIZE ; p_memsz = 8 bytes dq 0x100000 ; p_align = 8 bytes ; total 56 * 3 = 168 bytes .SIZE = $-Elf64_Phdr SYS_exit = 60 _start: call [print] mov eax, SYS_exit xor edi, edi syscall print dq ? ; total 6+5+2+2+8 = 23 bytes DYNAMIC: .DT_NULL = 0 ; ignored = Marks the end of the dynamic array .DT_NEEDED = 1 ; d_val = The string table offset of the name of a needed library. .DT_STRTAB = 5 ; d_ptr = Address of the dynamic string table. .DT_SYMTAB = 6 ; d_ptr = Address of the dynamic symbol table. .DT_RELA = 7 ; d_ptr = Address of a relocation table with Elf64_Rela entries. .DT_RELASZ = 8 ; d_val = Total size, in bytes, of the DT_RELA relocation table. .DT_RELAENT = 9 ; d_val = Size, in bytes, of each DT_RELA relocation entry. .DT_STRSZ = 10 ; d_val = Total size, in bytes, of the string table. .DT_SYMENT = 11 ; d_val = Size, in bytes, of each symbol table entry. dq DYNAMIC.DT_NEEDED, STRTAB.libshared dq DYNAMIC.DT_STRTAB, STRTAB dq DYNAMIC.DT_SYMTAB, SYMTAB dq DYNAMIC.DT_STRSZ, STRTAB.SIZE dq DYNAMIC.DT_SYMENT, 24 dq DYNAMIC.DT_RELA, RELA dq DYNAMIC.DT_RELASZ, RELA.SIZE dq DYNAMIC.DT_RELAENT, 24 dq DYNAMIC.DT_NULL, 0 .SIZE = $-DYNAMIC ; total 16 * 9 = 144 bytes SYMTAB: .STB_GLOBAL = 1 .STT_FUNC = 2 .STN_UNDEF = ($-SYMTAB)/24 dd 0 ; u32 st_name = 0 db 0 ; u8 st_info = 0 db 0 ; u8 st_other = 0 dw 0 ; u16 st_shndx = SHN_UNDEF dq 0 ; u64 st_value = 0 dq 0 ; u64 st_size = 0 .print=($-SYMTAB)/24 dd STRTAB.print ; u32 st_name db SYMTAB.STB_GLOBAL shl 4 + SYMTAB.STT_FUNC ; u8 st_info db 0 ; u8 st_other dw 0 ; u16 st_shndx dq 0 ; u64 st_value dq 0 ; u64 st_size .SIZE=$-SYMTAB ; total 24 * 2 = 48 bytes RELA: .R_AMD64_64 = 1 dq print ; reloc addess dq SYMTAB.print shl 32 + RELA.R_AMD64_64 ; symtab_index shl 32 + type dq 0 ; addend .SIZE=$-RELA ; total = 24 bytes STRTAB: .null=$-STRTAB db 0 .libshared=$-STRTAB db "libshared.so", 0 .print=$-STRTAB db "print", 0 .SIZE=$-STRTAB ; total = 20 bytes _interpreter_name_: db "/lib/ld-linux-x86-64.so.2", 0 .SIZE = $-_interpreter_name_ ; total = 26 bytes FILE.SIZE=$-$$ ; file size in total is 517 bytes Last edited by reyuki on 26 Jan 2025, 15:19; edited 1 time in total |
|||
![]() |
|
revolution 26 Jan 2025, 13:36
Try putting align before DYNAMIC
Code: align 8 DYNAMIC: |
|||
![]() |
|
reyuki 26 Jan 2025, 15:18
Ah, yes I forgot to re-adjust the p_offset and p_vaddr of PT_LOAD (previously I only load the the _start segment instead of a whole file content but then STRTAB, SYMTAB and RELA need to be loaded to the memory as well, so I choose to load the whole content XD)
and as you said, no need alignment if the whole content is loaded into the memory, but wouldn't this make the flags on PT_INTERP and PT_DYNAMIC become RWX because they are overwritten? I guess it doesn't really matter or important though, the segfault is gone anyway. thank you for the help revolution, bitRAKE ^^ Last edited by reyuki on 26 Jan 2025, 15:33; edited 1 time in total |
|||
![]() |
|
reyuki 26 Jan 2025, 15:31
by the way, the readelf's output show some error:
Code: 'RELA' relocation section at offset 0x4001bf contains 24 bytes: Offset Info Type Symbol's Value Symbol's Name + Addend 00000000004000f7 0000000100000001 R_X86_64_64 readelf: Error: bad symbol index: 00000001 in reloc what do I need to fix the error? If I read the readelf's source code it seems have todo with symtab? I guess this is normal if I create the executable from scratch, I assume because the libc example have same issue Last edited by reyuki on 26 Jan 2025, 23:43; edited 1 time in total |
|||
![]() |
|
bitRAKE 26 Jan 2025, 15:52
reyuki wrote: but wouldn't this make the flags on PT_INTERP and PT_DYNAMIC become RWX because they are overwritten? |
|||
![]() |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.